Coverage Report

Created: 2026-09-27 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/open62541_15/plugins/ua_log_syslog.c
Line
Count
Source
1
/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
2
 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
3
 *
4
 *    Copyright 2020 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
5
 */
6
7
#include <open62541/plugin/log_syslog.h>
8
#include <open62541/types.h>
9
10
#if defined(__linux__) || defined(__unix__)
11
12
#include <syslog.h>
13
#include "mp_printf.h"
14
15
static const char *syslogLevelNames[6] = {"trace", "debug", "info",
16
                                   "warn", "error", "fatal"};
17
static const char *syslogCategoryNames[UA_LOGCATEGORIES] =
18
    {"network", "channel", "session", "server", "client",
19
     "application", "security", "eventloop", "pubsub", "discovery"};
20
21
static const char *
22
0
syslogCategoryName(UA_LogCategory category) {
23
0
    if((UA_UInt32)category >= UA_LOGCATEGORIES)
24
0
        return "unknown";
25
0
    return syslogCategoryNames[category];
26
0
}
27
28
#ifdef __clang__
29
__attribute__((__format__(__printf__, 4 , 0)))
30
#endif
31
static void
32
UA_Log_Syslog_log(void *context, UA_LogLevel level, UA_LogCategory category,
33
0
                  const char *msg, va_list args) {
34
    /* Assume that context is casted to UA_LogLevel */
35
0
    if(context != NULL && (UA_LogLevel)(uintptr_t)context > level)
36
0
        return;
37
38
0
    int priority = LOG_INFO;
39
0
    switch(level) {
40
0
    case UA_LOGLEVEL_DEBUG:
41
0
        priority = LOG_DEBUG;
42
0
        break;
43
0
    case UA_LOGLEVEL_INFO:
44
0
        priority = LOG_INFO;
45
0
        break;
46
0
    case UA_LOGLEVEL_WARNING:
47
0
        priority = LOG_WARNING;
48
0
        break;
49
0
    case UA_LOGLEVEL_ERROR:
50
0
        priority = LOG_ERR;
51
0
        break;
52
0
    case UA_LOGLEVEL_FATAL:
53
0
        priority = LOG_CRIT;
54
0
        break;
55
0
    case UA_LOGLEVEL_TRACE:
56
0
    default:
57
0
        return;
58
0
    }
59
60
0
    int logLevelSlot = ((int)level / 100) - 1;
61
62
0
#define LOGBUFSIZE 512
63
0
    char logbuf[LOGBUFSIZE];
64
0
    int pos = mp_snprintf(logbuf, LOGBUFSIZE, "[%s/%s] ",
65
0
                          syslogLevelNames[logLevelSlot],
66
0
                          syslogCategoryName(category));
67
0
    if(pos < 0) {
68
0
        syslog(LOG_WARNING, "Log message too long for syslog");
69
0
        return;
70
0
    }
71
0
    pos = mp_vsnprintf(&logbuf[pos], LOGBUFSIZE - (size_t)pos, msg, args);
72
0
    if(pos < 0) {
73
0
        syslog(LOG_WARNING, "Log message too long for syslog");
74
0
        return;
75
0
    }
76
77
0
    syslog(priority, "%s", logbuf);
78
0
}
79
80
static void
81
0
UA_Log_Syslog_clear(UA_Logger *logger) {
82
    /* closelog is optional. We don't use it as several loggers might be
83
     * instantiated in parallel. */
84
    /* closelog(); */
85
0
    UA_free(logger);
86
0
}
87
88
UA_Logger
89
0
UA_Log_Syslog(void) {
90
0
    return UA_Log_Syslog_withLevel(UA_LOGLEVEL_TRACE);
91
0
}
92
93
UA_Logger
94
0
UA_Log_Syslog_withLevel(UA_LogLevel minlevel) {
95
0
    UA_Logger logger = {UA_Log_Syslog_log, (void*)(uintptr_t)minlevel, NULL};
96
0
    return logger;
97
0
}
98
99
UA_Logger *
100
0
UA_Log_Syslog_new(UA_LogLevel minlevel) {
101
0
    UA_Logger *logger = (UA_Logger*)UA_malloc(sizeof(UA_Logger));
102
0
    if(!logger)
103
0
        return NULL;
104
0
    *logger = UA_Log_Syslog_withLevel(minlevel);
105
0
    logger->clear = UA_Log_Syslog_clear;
106
0
    return logger;
107
0
}
108
109
#endif