summaryrefslogtreecommitdiffstats
path: root/src/aclk/mqtt_websockets/mqtt_wss_log.c
blob: 5e606c12becdf81ba7dcc14798ecfa74cb71fa1c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright: SPDX-License-Identifier:  GPL-3.0-only

#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>

#include "mqtt_wss_log.h"
#include "common_internal.h"

struct mqtt_wss_log_ctx {
    mqtt_wss_log_callback_t extern_log_fnc;
    char *ctx_prefix;
    char *buffer;
    char *buffer_w_ptr;
    size_t buffer_bytes_avail;
};

#define LOG_BUFFER_SIZE 1024 * 4
#define LOG_CTX_PREFIX_SEV_STR "  : "
#define LOG_CTX_PREFIX_LIMIT 15
#define LOG_CTX_PREFIX_LIMIT_STR (LOG_CTX_PREFIX_LIMIT - (2 + strlen(LOG_CTX_PREFIX_SEV_STR)))  // with [] characters and affixed ' ' it is total 15 chars
#if (LOG_CTX_PREFIX_LIMIT * 10) > LOG_BUFFER_SIZE
#error "LOG_BUFFER_SIZE too small"
#endif
mqtt_wss_log_ctx_t mqtt_wss_log_ctx_create(const char *ctx_prefix, mqtt_wss_log_callback_t log_callback)
{
    mqtt_wss_log_ctx_t ctx = mw_calloc(1, sizeof(struct mqtt_wss_log_ctx));
    if(!ctx)
        return NULL;

    if(log_callback) {
        ctx->extern_log_fnc = log_callback;
        ctx->buffer = mw_calloc(1, LOG_BUFFER_SIZE);
        if(!ctx->buffer)
            goto cleanup;

        ctx->buffer_w_ptr = ctx->buffer;
        if(ctx_prefix) {
            *(ctx->buffer_w_ptr++) = '[';
            strncpy(ctx->buffer_w_ptr, ctx_prefix, LOG_CTX_PREFIX_LIMIT_STR);
            ctx->buffer_w_ptr += strnlen(ctx_prefix, LOG_CTX_PREFIX_LIMIT_STR);
            *(ctx->buffer_w_ptr++) = ']';
        }
        strcpy(ctx->buffer_w_ptr, LOG_CTX_PREFIX_SEV_STR);
        ctx->buffer_w_ptr += strlen(LOG_CTX_PREFIX_SEV_STR);
        // no term '\0' -> calloc is used

        ctx->buffer_bytes_avail = LOG_BUFFER_SIZE - strlen(ctx->buffer);

        return ctx;
    }

    if(ctx_prefix) {
        ctx->ctx_prefix = strndup(ctx_prefix, LOG_CTX_PREFIX_LIMIT_STR);
        if(!ctx->ctx_prefix)
            goto cleanup;
    }

    return ctx;

cleanup:
    mw_free(ctx);
    return NULL;
}

void mqtt_wss_log_ctx_destroy(mqtt_wss_log_ctx_t ctx)
{
    mw_free(ctx->ctx_prefix);
    mw_free(ctx->buffer);
    mw_free(ctx);
}

static inline char severity_to_c(int severity)
{
    switch (severity) {
        case MQTT_WSS_LOG_FATAL:
            return 'F';
        case MQTT_WSS_LOG_ERROR:
            return 'E';
        case MQTT_WSS_LOG_WARN:
            return 'W';
        case MQTT_WSS_LOG_INFO:
            return 'I';
        case MQTT_WSS_LOG_DEBUG:
            return 'D';
        default:
            return '?';
    }
}

void mws_log(int severity, mqtt_wss_log_ctx_t ctx, const char *fmt, va_list args)
{
    size_t size;

    if(ctx->extern_log_fnc) {
        size = vsnprintf(ctx->buffer_w_ptr, ctx->buffer_bytes_avail, fmt, args);
        *(ctx->buffer_w_ptr - 3) = severity_to_c(severity);

        ctx->extern_log_fnc(severity, ctx->buffer);

        if(size >= ctx->buffer_bytes_avail)
            mws_error(ctx, "Last message of this type was truncated! Consider what you log or increase LOG_BUFFER_SIZE if really needed.");

        return;
    }

    if(ctx->ctx_prefix)
        printf("[%s] ", ctx->ctx_prefix);

    printf("%c: ", severity_to_c(severity));

    vprintf(fmt, args);
    putchar('\n');
}

#define DEFINE_MWS_SEV_FNC(severity_fncname, severity) \
void mws_ ## severity_fncname(mqtt_wss_log_ctx_t ctx, const char *fmt, ...) \
{ \
    va_list args; \
    va_start(args, fmt); \
    mws_log(severity, ctx, fmt, args); \
    va_end(args); \
}

DEFINE_MWS_SEV_FNC(fatal, MQTT_WSS_LOG_FATAL)
DEFINE_MWS_SEV_FNC(error, MQTT_WSS_LOG_ERROR)
DEFINE_MWS_SEV_FNC(warn,  MQTT_WSS_LOG_WARN )
DEFINE_MWS_SEV_FNC(info,  MQTT_WSS_LOG_INFO )
DEFINE_MWS_SEV_FNC(debug, MQTT_WSS_LOG_DEBUG)