GCC Code Coverage Report


Directory: src/gate/
File: src/gate/io/logging.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 81 200 40.5%
Functions: 9 19 47.4%
Branches: 15 80 18.8%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/io/logging.h"
30 #include "gate/times.h"
31 #include "gate/threading.h"
32 #include "gate/processes.h"
33 #include "gate/streams.h"
34 #include "gate/console.h"
35 #include "gate/files.h"
36 #include "gate/environments.h"
37 #include "gate/results.h"
38
39 #if defined(GATE_SYS_WIN16)
40 # define GATE_IO_LOGGING_NO_IMPL 1
41 #elif defined(GATE_SYS_WIN)
42 # define GATE_IO_LOGGING_WINAPI_IMPL 1
43 #elif defined(GATE_SYS_POSIX)
44 # define GATE_IO_LOGGING_POSIX_IMPL 1
45 #else
46 # define GATE_IO_LOGGING_NO_IMPL 1
47 #endif
48
49
50 #define GATE_LOGGING_STDERR_LOG_TYPE GATE_LOG_TYPE_STATUS
51
52 6 static char const* gate_logging_print_type(gate_enumint_t log_type)
53 {
54
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (log_type >= GATE_LOG_TYPE_FATAL) return "FATAL";
55
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (log_type >= GATE_LOG_TYPE_ERROR) return "ERROR";
56
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (log_type >= GATE_LOG_TYPE_WARN) return "WARN";
57 if (log_type >= GATE_LOG_TYPE_STATUS) return "STATUS";
58 if (log_type >= GATE_LOG_TYPE_INFO) return "INFO";
59 if (log_type >= GATE_LOG_TYPE_DEBUG) return "DEBUG";
60 if (log_type >= GATE_LOG_TYPE_TRACE) return "TRACE";
61 return "";
62 }
63
64 6 static gate_size_t gate_logging_create_line(char* buffer, gate_size_t buffer_len,
65 char const* separator,
66 gate_enumint_t log_type, gate_result_t result_code, gate_int32_t native_code,
67 gate_string_t const* origin, gate_string_t const* message)
68 {
69 6 gate_size_t ret = 0;
70 gate_strbuilder_t builder;
71 6 gate_process_id_t pid = 0;
72 6 gate_thread_id_t tid = 0;
73 6 gate_time_t now = GATE_INIT_EMPTY;
74 6 char time_buffer[64] = GATE_INIT_EMPTY;
75 6 gate_size_t time_buffer_size = sizeof(time_buffer);
76
77 6 gate_time_now(&now);
78 6 gate_time_to_string(&now, NULL, time_buffer, &time_buffer_size);
79
80 6 gate_process_get_id(&pid);
81 6 gate_thread_current(NULL, &tid);
82
83 6 gate_strbuilder_create_static(&builder, buffer, buffer_len, 0);
84 6 gate_strbuilder_append(&builder,
85 GATE_PRINT_CSTR, time_buffer,
86 GATE_PRINT_CSTR, separator,
87 GATE_PRINT_CSTR, "P", GATE_PRINT_UI64, (gate_uint64_t)pid,
88 GATE_PRINT_CSTR, ".", GATE_PRINT_UI64, (gate_uint64_t)tid,
89 GATE_PRINT_CSTR, separator, GATE_PRINT_CSTR, gate_logging_print_type(log_type),
90 GATE_PRINT_CSTR, separator, GATE_PRINT_I32, (gate_int32_t)result_code,
91 GATE_PRINT_CSTR, separator, GATE_PRINT_I32, native_code,
92 GATE_PRINT_CSTR, separator, GATE_PRINT_STRING, origin,
93 GATE_PRINT_CSTR, separator, GATE_PRINT_STRING, message,
94 GATE_PRINT_NEWLINE,
95 GATE_PRINT_END);
96
97 6 ret = gate_strbuilder_length(&builder);
98
99 6 gate_strbuilder_release(&builder);
100 6 return ret;
101 }
102
103 static gate_bool_t gate_global_stderr_enabled(gate_logger_t const* logger, gate_enumint_t log_type)
104 {
105 GATE_UNUSED_ARG(logger);
106 return log_type >= GATE_LOGGING_STDERR_LOG_TYPE;
107 }
108
109 12 static gate_result_t gate_global_stderr_log(gate_logger_t const* logger,
110 gate_enumint_t log_type, gate_result_t result_code, gate_int32_t native_code,
111 gate_string_t const* origin, gate_string_t const* message)
112 {
113 12 gate_result_t ret = GATE_RESULT_OK;
114 char buffer[8192];
115 gate_size_t used;
116
117 GATE_UNUSED_ARG(logger);
118
119
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (log_type >= GATE_LOG_TYPE_WARN)
120 {
121 6 used = gate_logging_create_line(buffer, sizeof(buffer), "\t", log_type, result_code, native_code, origin, message);
122 6 gate_console_write_err(gate_console(), buffer, used);
123 }
124 12 return ret;
125 }
126
127
128 static gate_logger_t gate_stderr_logger =
129 {
130 &gate_global_stderr_log,
131 &gate_global_stderr_enabled
132 };
133
134 static gate_logger_t* volatile gate_current_global_logger = &gate_stderr_logger;
135
136
137
138 static gate_bool_t gate_filelogger_enabled(gate_logger_t const* logger, gate_enumint_t log_type)
139 {
140 gate_filelogger_t* file_logger = (gate_filelogger_t*)logger;
141 return log_type >= file_logger->log_level;
142 }
143
144 static gate_result_t gate_filelogger_log(gate_logger_t const* logger,
145 gate_enumint_t log_type, gate_result_t result_code, gate_int32_t native_code,
146 gate_string_t const* origin, gate_string_t const* message)
147 {
148 gate_result_t ret = GATE_RESULT_OK;
149 gate_filelogger_t* file_logger = (gate_filelogger_t*)logger;
150 char buffer[8192];
151 gate_size_t used;
152 gate_file_t file;
153 gate_size_t written;
154 gate_size_t written_total = 0;
155
156 do
157 {
158 if (log_type < file_logger->log_level)
159 {
160 /* log type is filted out */
161 break;
162 }
163
164 used = gate_logging_create_line(buffer, sizeof(buffer), "\t", log_type, result_code, native_code, origin, message);
165
166 ret = gate_mutex_acquire(&file_logger->mutex);
167 GATE_BREAK_IF_FAILED(ret);
168
169 do
170 {
171 ret = gate_file_open(&file_logger->output_file, GATE_STREAM_OPEN_APPENDWRITE | GATE_FILE_OPEN_SHARED, &file);
172 GATE_BREAK_IF_FAILED(ret);
173
174 do
175 {
176 ret = gate_file_lock(file, true);
177 GATE_BREAK_IF_FAILED(ret);
178
179 ret = gate_file_seek(file, 0, GATE_FILE_SEEK_ORIGIN_END, NULL);
180 if (GATE_SUCCEEDED(ret))
181 {
182 while (written_total < used)
183 {
184 ret = gate_file_write(file, &buffer[written_total], used - written_total, &written);
185 GATE_BREAK_IF_FAILED(ret);
186 written_total += written;
187 }
188 }
189 gate_file_flush(file);
190 gate_file_unlock(file);
191 } while (0);
192
193 gate_file_close(file);
194 } while (0);
195
196 gate_mutex_release(&file_logger->mutex);
197
198 } while (0);
199
200 return ret;
201 }
202
203 1 gate_result_t gate_filelogger_create(gate_filelogger_t* logger, gate_string_t const* output_file, gate_enumint_t log_level)
204 {
205 1 gate_result_t ret = GATE_RESULT_FAILED;
206 gate_file_t file;
207
208 1 ret = gate_file_open(output_file, GATE_STREAM_OPEN_APPENDWRITE | GATE_FILE_OPEN_SHARED, &file);
209
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (GATE_SUCCEEDED(ret))
210 {
211 1 gate_mem_clear(logger, sizeof(gate_filelogger_t));
212
213 1 gate_file_close(file);
214
215 1 ret = gate_mutex_create(&logger->mutex);
216
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (GATE_SUCCEEDED(ret))
217 {
218 1 gate_string_clone(&logger->output_file, output_file);
219 1 logger->logger_base.log = &gate_filelogger_log;
220 1 logger->logger_base.enabled = &gate_filelogger_enabled;
221 1 logger->log_level = log_level;
222 }
223 }
224
225 1 return ret;
226 }
227 1 gate_result_t gate_filelogger_destroy(gate_filelogger_t* logger)
228 {
229 1 gate_string_release(&logger->output_file);
230 1 gate_mutex_destroy(&logger->mutex);
231 1 gate_mem_clear(logger, sizeof(gate_filelogger_t));
232 1 return GATE_RESULT_OK;
233 }
234
235
236
237
238
239
240
241 12 gate_result_t gate_log(gate_logger_t const* logger,
242 gate_enumint_t log_type, gate_result_t result_code, gate_int32_t native_code,
243 gate_string_t const* origin, gate_string_t const* message)
244 {
245
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 if (logger && logger->log)
246 {
247 12 return logger->log(logger, log_type, result_code, native_code, origin, message);
248 }
249 else
250 {
251 return GATE_RESULT_NOTAVAILABLE;
252 }
253 }
254
255 gate_result_t gate_log_str(gate_logger_t const* logger,
256 gate_enumint_t log_type, gate_result_t result_code, gate_int32_t native_code,
257 char const* origin, char const* message)
258 {
259 gate_string_t str_origin;
260 gate_string_t str_msg;
261
262 gate_string_create_static(&str_origin, origin);
263 gate_string_create_static(&str_msg, message);
264 return gate_log(logger, log_type, result_code, native_code, &str_origin, &str_msg);
265 }
266
267
268 gate_bool_t gate_log_enabled(gate_logger_t const* logger,
269 gate_enumint_t log_type)
270 {
271 if (logger && logger->enabled)
272 {
273 return logger->enabled(logger, log_type);
274 }
275 else
276 {
277 return false;
278 }
279 }
280
281
282
283 static gate_filelogger_t global_file_logger = GATE_INIT_EMPTY;
284
285 1 gate_result_t gate_logger_start(gate_string_t const* output_file, gate_enumint_t log_level)
286 {
287 1 gate_result_t ret = GATE_RESULT_INVALIDSTATE;
288 1 gate_string_t tmp_file = GATE_STRING_INIT_EMPTY;
289 1 gate_strbuilder_t builder = GATE_INIT_EMPTY;
290 1 gate_string_t tmp_root = GATE_STRING_INIT_EMPTY;
291 char name[GATE_MAX_FILENAME_LENGTH];
292 1 gate_size_t name_len = sizeof(name);
293 1 gate_process_id_t pid = 0;
294
295
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (gate_current_global_logger != &global_file_logger.logger_base)
296 {
297
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (gate_string_is_empty(output_file))
298 {
299 1 gate_process_get_id(&pid);
300 1 gate_env_app_executable_name_str(name, &name_len);
301 1 gate_env_temp_rootpath(&tmp_root);
302 1 gate_strbuilder_create(&builder, 0);
303 1 gate_strbuilder_append_string(&builder, &tmp_root);
304 1 gate_strbuilder_append_cstr(&builder, name);
305 1 gate_strbuilder_append_cstr(&builder, "_");
306 1 gate_strbuilder_append_int64(&builder, (gate_int64_t)pid);
307 1 gate_strbuilder_append_cstr(&builder, ".log");
308 1 gate_strbuilder_to_string(&builder, &tmp_file);
309 }
310 else
311 {
312 gate_string_clone(&tmp_file, output_file);
313 }
314
315 1 ret = gate_filelogger_create(&global_file_logger, &tmp_file, log_level);
316
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (GATE_SUCCEEDED(ret))
317 {
318 1 gate_current_global_logger = &global_file_logger.logger_base;
319 }
320 }
321
322 1 gate_strbuilder_release(&builder);
323 1 gate_string_release(&tmp_file);
324 1 gate_string_release(&tmp_root);
325
326 1 return ret;
327 }
328 1 gate_logger_t const* gate_logger_get()
329 {
330 1 return gate_current_global_logger;
331 }
332 1 gate_result_t gate_logger_stop()
333 {
334 1 gate_result_t ret = GATE_RESULT_OK;
335
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (gate_current_global_logger == &global_file_logger.logger_base)
336 {
337 1 gate_current_global_logger = &gate_stderr_logger;
338 1 ret = gate_filelogger_destroy(&global_file_logger);
339 }
340 1 return ret;
341 }
342
343
344
345
346
347 #if defined(GATE_IO_LOGGING_WINAPI_IMPL)
348
349 #include "gate/platform/windows/win32registry.h"
350 #include "gate/environments.h"
351
352
353 typedef struct gate_syslogger_class
354 {
355 gate_logger_t logger_base;
356
357 TCHAR app_name[GATE_MAX_FILENAME_LENGTH];
358 HANDLE heventlog;
359
360 } gate_syslogger_t;
361
362 static gate_syslogger_t global_syslogger = GATE_INIT_EMPTY;
363 static gate_atomic_flag_t global_syslogger_initialized = GATE_ATOMIC_FLAG_INIT;
364
365
366 static gate_bool_t syslogger_enabled(struct gate_logger_class const* logger, gate_enumint_t log_type)
367 {
368 (void)logger;
369 (void)log_type;
370 return true;
371 }
372
373 static gate_result_t syslogger_log(struct gate_logger_class const* logger,
374 gate_enumint_t log_type, gate_result_t result_code, gate_int32_t native_code,
375 gate_string_t const* origin, gate_string_t const* message)
376 {
377 gate_result_t ret = GATE_RESULT_FAILED;
378 gate_syslogger_t const* impl = (gate_syslogger_t const*)logger;
379 WORD wType = EVENTLOG_INFORMATION_TYPE;
380 WORD wCategory = 0;
381 DWORD dwEventId = (result_code == 0) ? 0 : (65536 + result_code);
382 TCHAR msg_buffer[4096];
383 gate_size_t msg_buffer_capacity = sizeof(msg_buffer) / sizeof(msg_buffer[0]);
384 gate_size_t msg_buffer_used;
385 TCHAR const* ptr_buffer = &msg_buffer[0];
386
387 do
388 {
389 if (log_type <= GATE_LOG_TYPE_DEBUG)
390 {
391 /* debug messages should not be logged in system log */
392 return GATE_RESULT_OK;
393 }
394 else if (log_type <= GATE_LOG_TYPE_INFO)
395 {
396 wType = GATE_SUCCEEDED(result_code) ? EVENTLOG_SUCCESS : EVENTLOG_INFORMATION_TYPE;
397 }
398 else if (log_type <= GATE_LOG_TYPE_STATUS)
399 {
400 wType = GATE_SUCCEEDED(result_code) ? EVENTLOG_AUDIT_SUCCESS : EVENTLOG_AUDIT_FAILURE;
401 }
402 else if (log_type <= GATE_LOG_TYPE_WARN)
403 {
404 wType = EVENTLOG_WARNING_TYPE;
405 }
406 else if (log_type <= GATE_LOG_TYPE_ERROR)
407 {
408 wType = EVENTLOG_ERROR_TYPE;
409 }
410 else if (log_type <= GATE_LOG_TYPE_FATAL)
411 {
412 wType = EVENTLOG_ERROR_TYPE;
413 }
414
415 msg_buffer_used = 0;
416 if (GATE_FAILED(result_code))
417 {
418 msg_buffer_used += gate_win32_winstr_print_text(
419 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, _T("Result: "), 8);
420 msg_buffer_used += gate_win32_winstr_print_int32(
421 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, (gate_int32_t)result_code);
422 msg_buffer_used += gate_win32_winstr_print_text(
423 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, _T("\r\n"), 2);
424 }
425 if (native_code != 0)
426 {
427 msg_buffer_used += gate_win32_winstr_print_text(
428 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, _T("Code: "), 6);
429 msg_buffer_used += gate_win32_winstr_print_int32(
430 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, (gate_int32_t)native_code);
431 msg_buffer_used += gate_win32_winstr_print_text(
432 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, _T("\r\n"), 2);
433 }
434 if (!gate_string_is_empty(origin))
435 {
436 msg_buffer_used += gate_win32_winstr_print_text(
437 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, _T("Origin: "), 8);
438 msg_buffer_used += gate_win32_utf8_2_winstr(
439 origin->str, origin->length, &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used);
440 msg_buffer_used += gate_win32_winstr_print_text(
441 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, _T("\r\n"), 2);
442 }
443 if (!gate_string_is_empty(message))
444 {
445 msg_buffer_used += gate_win32_utf8_2_winstr(
446 message->str, message->length, &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used);
447 }
448
449 #if !defined(GATE_SYS_WINCE)
450 if (gate_platform.AdvReportEvent(impl->heventlog, wType, wCategory, dwEventId, NULL, 1, 0, &ptr_buffer, NULL))
451 {
452 ret = GATE_RESULT_OK;
453 }
454 #endif
455
456 } while (0);
457 return ret;
458 }
459
460 gate_result_t gate_syslog_start()
461 {
462 gate_result_t ret = GATE_RESULT_FAILED;
463 gate_result_t result;
464 char app_name[GATE_MAX_FILENAME_LENGTH] = GATE_INIT_EMPTY;
465 gate_size_t app_name_len = sizeof(app_name);
466
467 do
468 {
469 if (gate_atomic_flag_set(&global_syslogger_initialized))
470 {
471 ret = GATE_RESULT_OK;
472 break;
473 }
474 #if !defined(GATE_SYS_WINCE)
475 if (!gate_platform.AdvRegisterEventSource || !gate_platform.AdvDeregisterEventSource || !gate_platform.AdvReportEvent)
476 #endif
477 {
478 ret = GATE_RESULT_NOTSUPPORTED;
479 break;
480 }
481
482 result = gate_env_app_executable_name_str(app_name, &app_name_len);
483 if (GATE_FAILED(result))
484 {
485 app_name_len = GATE_STR_PRINT_TEXT(app_name, "gate-logs");
486 }
487
488 gate_win32_utf8_2_winstr(app_name, app_name_len, global_syslogger.app_name,
489 sizeof(global_syslogger.app_name) / sizeof(global_syslogger.app_name[0]));
490
491 #if !defined(GATE_SYS_WINCE)
492 global_syslogger.heventlog = gate_platform.AdvRegisterEventSource(NULL, global_syslogger.app_name);
493 #endif
494 if (NULL == global_syslogger.heventlog)
495 {
496 ret = GATE_RESULT_FAILED;
497 break;
498 }
499
500 global_syslogger.logger_base.log = &syslogger_log;
501 global_syslogger.logger_base.enabled = &syslogger_enabled;
502 ret = GATE_RESULT_OK;
503 } while (0);
504
505 if (GATE_FAILED(ret))
506 {
507 gate_atomic_flag_clear(&global_syslogger_initialized);
508 }
509
510 return ret;
511 }
512
513 gate_result_t gate_syslog_stop()
514 {
515 gate_result_t ret = GATE_RESULT_OK;
516 if (gate_atomic_flag_set(&global_syslogger_initialized))
517 {
518 #if !defined(GATE_SYS_WINCE)
519 gate_platform.AdvDeregisterEventSource(global_syslogger.heventlog);
520 #endif
521 }
522 gate_atomic_flag_clear(&global_syslogger_initialized);
523 return ret;
524 }
525
526 gate_logger_t const* gate_syslog_get()
527 {
528 gate_result_t result = gate_syslog_start();
529
530 if (GATE_SUCCEEDED(result))
531 {
532 return &global_syslogger.logger_base;
533 }
534 else
535 {
536 return gate_logger_get();
537 }
538 }
539
540 #endif /* GATE_IO_LOGGING_WINAPI_IMPL */
541
542
543 #if defined(GATE_IO_LOGGING_POSIX_IMPL)
544
545 #include <syslog.h>
546
547
548 typedef struct gate_syslogger_class
549 {
550 gate_logger_t logger_base;
551
552 } gate_syslogger_t;
553
554 static gate_syslogger_t global_syslogger = GATE_INIT_EMPTY;
555 static gate_atomic_flag_t global_syslogger_initialized = GATE_ATOMIC_FLAG_INIT;
556
557 static gate_bool_t syslogger_enabled(struct gate_logger_class const* logger, gate_enumint_t log_type)
558 {
559 (void)logger;
560 (void)log_type;
561 return true;
562 }
563
564 static gate_result_t syslogger_log(struct gate_logger_class const* logger,
565 gate_enumint_t log_type, gate_result_t result_code, gate_int32_t native_code,
566 gate_string_t const* origin, gate_string_t const* message)
567 {
568 gate_result_t ret = GATE_RESULT_FAILED;
569 /*gate_syslogger_t const* impl = (gate_syslogger_t const*)logger;*/
570 char priority = LOG_USER;
571 char msg_buffer[4096];
572 gate_size_t msg_buffer_capacity = sizeof(msg_buffer) / sizeof(msg_buffer[0]);
573 gate_size_t msg_buffer_used;
574
575 do
576 {
577 if (log_type <= GATE_LOG_TYPE_DEBUG)
578 {
579 /* debug messages should not be logged in system log */
580 return GATE_RESULT_OK;
581 }
582 else if (log_type <= GATE_LOG_TYPE_INFO)
583 {
584 priority |= LOG_INFO;
585 }
586 else if (log_type <= GATE_LOG_TYPE_STATUS)
587 {
588 priority |= LOG_NOTICE;
589 }
590 else if (log_type <= GATE_LOG_TYPE_WARN)
591 {
592 priority |= LOG_WARNING;
593 }
594 else if (log_type <= GATE_LOG_TYPE_ERROR)
595 {
596 priority |= LOG_ERR;
597 }
598 else if (log_type <= GATE_LOG_TYPE_FATAL)
599 {
600 priority |= LOG_ALERT;
601 }
602
603 msg_buffer_used = 0;
604 if (GATE_FAILED(result_code))
605 {
606 msg_buffer_used += gate_str_print_text(
607 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, "Result: ", 8);
608 msg_buffer_used += gate_str_print_int32(
609 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, (gate_int32_t)result_code);
610 msg_buffer_used += gate_str_print_text(
611 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, "\r\n", 2);
612 }
613 if (native_code != 0)
614 {
615 msg_buffer_used += gate_str_print_text(
616 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, "Code: ", 6);
617 msg_buffer_used += gate_str_print_int32(
618 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, (gate_int32_t)native_code);
619 msg_buffer_used += gate_str_print_text(
620 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, "\r\n", 2);
621 }
622 if (!gate_string_is_empty(origin))
623 {
624 msg_buffer_used += gate_str_print_text(
625 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, "Origin: ", 8);
626 msg_buffer_used += gate_str_print_text(
627 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, origin->str, origin->length);
628 msg_buffer_used += gate_str_print_text(
629 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, "\r\n", 2);
630 }
631 if (!gate_string_is_empty(message))
632 {
633 msg_buffer_used += gate_str_print_text(
634 &msg_buffer[msg_buffer_used], msg_buffer_capacity - msg_buffer_used, message->str, message->length);
635 }
636
637 syslog(priority, "%s", msg_buffer);
638
639 ret = GATE_RESULT_OK;
640 } while (0);
641 return ret;
642 }
643
644
645 gate_result_t gate_syslog_start()
646 {
647 gate_result_t ret = GATE_RESULT_FAILED;
648 gate_result_t result;
649 char app_name[GATE_MAX_FILENAME_LENGTH] = GATE_INIT_EMPTY;
650 char const* ptr_app_name = &app_name[0];
651 gate_size_t app_name_len = sizeof(app_name);
652
653 do
654 {
655 if (gate_atomic_flag_set(&global_syslogger_initialized))
656 {
657 ret = GATE_RESULT_OK;
658 break;
659 }
660
661 result = gate_env_app_executable_name_str(app_name, &app_name_len);
662 if (GATE_FAILED(result))
663 {
664 ptr_app_name = NULL;
665 }
666
667 openlog(ptr_app_name, LOG_NOWAIT | LOG_NDELAY | LOG_PID, LOG_USER);
668
669 global_syslogger.logger_base.log = &syslogger_log;
670 global_syslogger.logger_base.enabled = &syslogger_enabled;
671
672 ret = GATE_RESULT_OK;
673 } while (0);
674
675 if (GATE_FAILED(ret))
676 {
677 gate_atomic_flag_clear(&global_syslogger_initialized);
678 }
679
680 return ret;
681
682 }
683 gate_logger_t const* gate_syslog_get()
684 {
685 gate_result_t result = gate_syslog_start();
686
687 if (GATE_SUCCEEDED(result))
688 {
689 return &global_syslogger.logger_base;
690 }
691 else
692 {
693 return gate_logger_get();
694 }
695 }
696 gate_result_t gate_syslog_stop()
697 {
698 gate_result_t ret = GATE_RESULT_OK;
699 if (gate_atomic_flag_set(&global_syslogger_initialized))
700 {
701 closelog();
702 }
703 gate_atomic_flag_clear(&global_syslogger_initialized);
704 return ret;
705 }
706
707
708 #endif /* GATE_IO_LOGGING_POSIX_IMPL */
709
710
711
712
713 #if defined(GATE_IO_LOGGING_NO_IMPL)
714
715 gate_result_t gate_syslog_start()
716 {
717 return GATE_RESULT_OK;
718 }
719 gate_logger_t const* gate_syslog_get()
720 {
721 return gate_logger_get();
722 }
723 gate_result_t gate_syslog_stop()
724 {
725 return GATE_RESULT_OK;
726 }
727
728 #endif /* GATE_IO_LOGGING_NO_IMPL */
729