Coverage Report

Created: 2025-06-09 06:12

/src/S2OPC/src/Common/helpers/sopc_logger.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Licensed to Systerel under one or more contributor license
3
 * agreements. See the NOTICE file distributed with this work
4
 * for additional information regarding copyright ownership.
5
 * Systerel licenses this file to you under the Apache
6
 * License, Version 2.0 (the "License"); you may not use this
7
 * file except in compliance with the License. You may obtain
8
 * a copy of the License at
9
 *
10
 *   http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied.  See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19
20
#include "sopc_logger.h"
21
22
#include <stdio.h>
23
#include <string.h>
24
25
#include "sopc_array.h"
26
#include "sopc_assert.h"
27
#include "sopc_common_constants.h"
28
#include "sopc_date_time.h"
29
#include "sopc_filesystem.h"
30
#include "sopc_helper_string.h"
31
#include "sopc_mem_alloc.h"
32
33
static const char* traceName = "Trace";
34
static char* filePath = NULL;
35
36
static SOPC_Log_Instance* commonTrace = NULL;
37
static SOPC_Log_Instance* clientServerTrace = NULL;
38
static SOPC_Log_Instance* pubSubTrace = NULL;
39
static SOPC_Log_Instance* secuAudit = NULL;
40
static SOPC_Log_Instance* opcUaAudit = NULL;
41
42
// User section logs:
43
typedef SOPC_Log_Instance* UserLogElement;
44
45
// Array containing all user log sections managed by toolkit.
46
static SOPC_Array* userLogArray = NULL;
47
static void userLogArray_Free_Func(void* data)
48
0
{
49
0
    UserLogElement elt = (UserLogElement) data;
50
0
    SOPC_Log_ClearInstance(&elt);
51
0
}
52
53
static const char* SOPC_Log_SecuAuditCategory = "SecuAudit";
54
55
/*
56
 * \brief Initializes the file logger and create the necessary log file(s)
57
 *
58
 * \param pLogInst  An existing log instance used to print in the same log file
59
60
 *
61
 * */
62
static bool SOPC_Logger_AuditInitialize(void);
63
64
bool SOPC_Logger_Initialize(const SOPC_Log_Configuration* const logConfiguration)
65
0
{
66
0
    if (NULL != filePath)
67
0
    {
68
        // Already configured.
69
0
        return false;
70
0
    }
71
72
0
    const SOPC_Log_System logSystem = (NULL == logConfiguration) ? SOPC_LOG_SYSTEM_NO_LOG : logConfiguration->logSystem;
73
74
0
    bool result = false;
75
76
0
    char* uniqueLogPrefix = SOPC_Time_GetStringOfCurrentTimeUTC(true);
77
0
    SOPC_ASSERT(NULL != uniqueLogPrefix);
78
79
    // Format is <date>_<traceName> : +2 = '_' and '\0'
80
0
    filePath = (char*) SOPC_Malloc(strlen(traceName) + strlen(uniqueLogPrefix) + 2);
81
0
    SOPC_ASSERT(NULL != filePath);
82
0
    sprintf(filePath, "%s_%s", traceName, uniqueLogPrefix);
83
0
    SOPC_Free(uniqueLogPrefix);
84
85
0
    switch (logSystem)
86
0
    {
87
0
    case SOPC_LOG_SYSTEM_FILE:
88
0
    {
89
0
        const SOPC_LogSystem_File_Configuration* logCfg = &logConfiguration->logSysConfig.fileSystemLogConfig;
90
0
        SOPC_CircularLogFile_Configuration conf = {.logDirPath = logCfg->logDirPath,
91
0
                                                   .logFileName = filePath,
92
0
                                                   .logMaxBytes = logCfg->logMaxBytes,
93
0
                                                   .logMaxFiles = logCfg->logMaxFiles};
94
0
        secuAudit = SOPC_Log_CreateFileInstance(&conf, SOPC_Log_SecuAuditCategory);
95
0
        result = SOPC_Logger_AuditInitialize();
96
97
0
        break;
98
0
    }
99
0
    case SOPC_LOG_SYSTEM_USER:
100
0
        secuAudit = SOPC_Log_CreateUserInstance(SOPC_Log_SecuAuditCategory,
101
0
                                                logConfiguration->logSysConfig.userSystemLogConfig.doLog);
102
0
        result = SOPC_Logger_AuditInitialize();
103
0
        break;
104
0
    case SOPC_LOG_SYSTEM_NO_LOG:
105
0
        result = true;
106
0
        break;
107
0
    default:
108
0
        result = false;
109
0
        break;
110
0
    }
111
0
    if (SOPC_LOG_SYSTEM_NO_LOG != logSystem)
112
0
    {
113
0
        if (result)
114
0
        {
115
0
            SOPC_Logger_SetTraceLogLevel(logConfiguration->logLevel);
116
0
        }
117
0
        else
118
0
        {
119
            /* Status stays OK given that we don't have other alternatives for now */
120
0
            fprintf(stderr, "ERROR: S2OPC Logs initialization failed!\n");
121
0
        }
122
0
    }
123
0
    return result;
124
0
}
125
126
SOPC_Log_Instance* SOPC_Logger_AddUserInstance(const char* category)
127
0
{
128
0
    SOPC_Log_Instance* result = NULL;
129
0
    if (NULL == userLogArray)
130
0
    {
131
0
        userLogArray = SOPC_Array_Create(sizeof(UserLogElement), 1, &userLogArray_Free_Func);
132
0
    }
133
0
    if (NULL != userLogArray)
134
0
    {
135
0
        result = SOPC_Log_CreateInstanceAssociation(secuAudit, category);
136
0
    }
137
0
    if (result != NULL)
138
0
    {
139
0
        const bool appendOk = SOPC_Array_Append_Values(userLogArray, result, 1);
140
0
        if (!appendOk)
141
0
        {
142
0
            SOPC_Log_ClearInstance(&result);
143
0
            result = NULL;
144
0
        }
145
0
    }
146
0
    return result;
147
0
}
148
149
static bool SOPC_Logger_AuditInitialize(void)
150
0
{
151
0
    bool result = false;
152
0
    if (secuAudit != NULL)
153
0
    {
154
0
        result = SOPC_Log_SetLogLevel(secuAudit, SOPC_LOG_LEVEL_INFO); // Set INFO level for secu audit
155
156
0
        if (result != false)
157
0
        {
158
0
            commonTrace = SOPC_Log_CreateInstanceAssociation(secuAudit, "Common");
159
0
            if (commonTrace == NULL)
160
0
            {
161
0
                SOPC_CONSOLE_PRINTF("WARNING: Common log creation failed, no Common log will be recorded !");
162
0
            }
163
164
0
            clientServerTrace = SOPC_Log_CreateInstanceAssociation(secuAudit, "ClientServer");
165
0
            if (clientServerTrace == NULL)
166
0
            {
167
0
                SOPC_CONSOLE_PRINTF(
168
0
                    "WARNING: ClientServer log creation failed, no ClientServer log will be recorded !");
169
0
            }
170
171
0
            pubSubTrace = SOPC_Log_CreateInstanceAssociation(secuAudit, "PubSub");
172
0
            if (pubSubTrace == NULL)
173
0
            {
174
0
                SOPC_CONSOLE_PRINTF("WARNING: PubSub log creation failed, no PubSub log will be recorded !");
175
0
            }
176
177
0
            opcUaAudit = SOPC_Log_CreateInstanceAssociation(secuAudit, "OpcUa");
178
0
            if (opcUaAudit == NULL)
179
0
            {
180
0
                SOPC_CONSOLE_PRINTF("WARNING: OpcUa audit log creation failed, no OpcUa audit log will be recorded !");
181
0
            }
182
0
            else
183
0
            {
184
0
                SOPC_Log_SetLogLevel(opcUaAudit, SOPC_LOG_LEVEL_INFO); // Set INFO level for opcUa audit
185
0
            }
186
0
        }
187
0
        else
188
0
        {
189
0
            SOPC_Log_ClearInstance(&secuAudit);
190
0
        }
191
0
    }
192
0
    else
193
0
    {
194
0
        SOPC_CONSOLE_PRINTF("WARNING: log creation failed, no log will be recorded !\n");
195
0
    }
196
0
    return result;
197
0
}
198
199
void SOPC_Logger_SetTraceLogLevel(SOPC_Log_Level level)
200
0
{
201
0
    if (commonTrace != NULL)
202
0
    {
203
0
        SOPC_Log_SetLogLevel(commonTrace, level);
204
0
    }
205
0
    if (clientServerTrace != NULL)
206
0
    {
207
0
        SOPC_Log_SetLogLevel(clientServerTrace, level);
208
0
    }
209
0
    if (pubSubTrace != NULL)
210
0
    {
211
0
        SOPC_Log_SetLogLevel(pubSubTrace, level);
212
0
    }
213
0
}
214
215
SOPC_Log_Level SOPC_Logger_GetTraceLogLevel(void)
216
0
{
217
0
    return SOPC_Log_GetLogLevel(commonTrace);
218
0
}
219
220
void SOPC_Logger_SetConsoleOutput(bool activate)
221
0
{
222
0
    if (secuAudit != NULL)
223
0
    {
224
0
        SOPC_Log_SetConsoleOutput(secuAudit, activate);
225
0
    }
226
0
    if (commonTrace != NULL)
227
0
    {
228
0
        SOPC_Log_SetConsoleOutput(commonTrace, activate);
229
0
    }
230
0
    if (opcUaAudit != NULL)
231
0
    {
232
0
        SOPC_Log_SetConsoleOutput(opcUaAudit, activate);
233
0
    }
234
0
    if (clientServerTrace != NULL)
235
0
    {
236
0
        SOPC_Log_SetConsoleOutput(clientServerTrace, activate);
237
0
    }
238
0
    if (pubSubTrace != NULL)
239
0
    {
240
0
        SOPC_Log_SetConsoleOutput(pubSubTrace, activate);
241
0
    }
242
0
}
243
244
static void logger_Trace(SOPC_Log_Module logModule, SOPC_Log_Level logLevel, const char* format, va_list args)
245
419
{
246
419
    switch (logModule)
247
419
    {
248
0
    case SOPC_LOG_MODULE_COMMON:
249
0
        if (commonTrace != NULL)
250
0
        {
251
0
            SOPC_Log_VTrace(commonTrace, logLevel, format, args);
252
0
        }
253
0
        break;
254
419
    case SOPC_LOG_MODULE_CLIENTSERVER:
255
419
        if (clientServerTrace != NULL)
256
0
        {
257
0
            SOPC_Log_VTrace(clientServerTrace, logLevel, format, args);
258
0
        }
259
419
        break;
260
0
    case SOPC_LOG_MODULE_PUBSUB:
261
0
        if (pubSubTrace != NULL)
262
0
        {
263
0
            SOPC_Log_VTrace(pubSubTrace, logLevel, format, args);
264
0
        }
265
0
        break;
266
0
    default:
267
0
        break;
268
419
    }
269
419
}
270
271
void SOPC_Logger_TraceError(SOPC_Log_Module logModule, const char* format, ...)
272
419
{
273
419
    va_list args;
274
419
    va_start(args, format);
275
419
    logger_Trace(logModule, SOPC_LOG_LEVEL_ERROR, format, args);
276
419
    va_end(args);
277
419
}
278
279
void SOPC_Logger_TraceWarning(SOPC_Log_Module logModule, const char* format, ...)
280
0
{
281
0
    va_list args;
282
0
    va_start(args, format);
283
0
    logger_Trace(logModule, SOPC_LOG_LEVEL_WARNING, format, args);
284
0
    va_end(args);
285
0
}
286
287
void SOPC_Logger_TraceInfo(SOPC_Log_Module logModule, const char* format, ...)
288
0
{
289
0
    va_list args;
290
0
    va_start(args, format);
291
0
    logger_Trace(logModule, SOPC_LOG_LEVEL_INFO, format, args);
292
0
    va_end(args);
293
0
}
294
295
void SOPC_Logger_TraceDebug(SOPC_Log_Module logModule, const char* format, ...)
296
0
{
297
0
    va_list args;
298
0
    va_start(args, format);
299
0
    logger_Trace(logModule, SOPC_LOG_LEVEL_DEBUG, format, args);
300
0
    va_end(args);
301
0
}
302
303
void SOPC_Logger_TraceSecurityAudit(const char* format, ...)
304
0
{
305
0
    va_list args;
306
0
    if (secuAudit != NULL)
307
0
    {
308
0
        va_start(args, format);
309
0
        SOPC_Log_VTrace(secuAudit, SOPC_LOG_LEVEL_INFO, format, args);
310
0
        va_end(args);
311
0
    }
312
0
}
313
314
void SOPC_Logger_TraceSecurityAuditWarning(const char* format, ...)
315
0
{
316
0
    va_list args;
317
0
    if (secuAudit != NULL)
318
0
    {
319
0
        va_start(args, format);
320
0
        SOPC_Log_VTrace(secuAudit, SOPC_LOG_LEVEL_WARNING, format, args);
321
0
        va_end(args);
322
0
    }
323
0
}
324
325
void SOPC_Logger_TraceOpcUaAudit(const char* format, ...)
326
0
{
327
0
    va_list args;
328
0
    if (opcUaAudit != NULL)
329
0
    {
330
0
        va_start(args, format);
331
0
        SOPC_Log_VTrace(opcUaAudit, SOPC_LOG_LEVEL_INFO, format, args);
332
0
        va_end(args);
333
0
    }
334
0
}
335
336
void SOPC_Logger_TraceOpcUaAuditWarning(const char* format, ...)
337
0
{
338
0
    va_list args;
339
0
    if (opcUaAudit != NULL)
340
0
    {
341
0
        va_start(args, format);
342
0
        SOPC_Log_VTrace(opcUaAudit, SOPC_LOG_LEVEL_WARNING, format, args);
343
0
        va_end(args);
344
0
    }
345
0
}
346
347
void SOPC_Logger_Clear(void)
348
0
{
349
0
    if (userLogArray == NULL)
350
0
    {
351
0
        SOPC_Array_Delete(userLogArray);
352
0
        userLogArray = NULL;
353
0
    }
354
0
    if (commonTrace != NULL)
355
0
    {
356
0
        SOPC_Log_ClearInstance(&commonTrace);
357
0
    }
358
0
    if (clientServerTrace != NULL)
359
0
    {
360
0
        SOPC_Log_ClearInstance(&clientServerTrace);
361
0
    }
362
0
    if (pubSubTrace != NULL)
363
0
    {
364
0
        SOPC_Log_ClearInstance(&pubSubTrace);
365
0
    }
366
0
    if (opcUaAudit != NULL)
367
0
    {
368
0
        SOPC_Log_ClearInstance(&opcUaAudit);
369
0
    }
370
    // secuAudit is the "actual" instance and must be deleted last.
371
0
    if (secuAudit != NULL)
372
0
    {
373
0
        SOPC_Log_ClearInstance(&secuAudit);
374
0
    }
375
0
    SOPC_Free(filePath);
376
0
    filePath = NULL;
377
0
}