1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#include "mos/syslog/syslog.hpp"
4
5#include "mos/platform/platform.hpp"
6#include "mos/tasks/task_types.hpp"
7#include "proto/syslog.pb.h"
8
9#include <mos/compiler.h>
10#include <mos/mos_global.h>
11#include <mos_stdio.hpp>
12#include <pb_encode.h>
13
14static spinlock_t global_syslog_lock;
15
16static void do_print_syslog(const pb_syslog_message *msg, const debug_info_entry *feat)
17{
18 const loglevel_t level = (loglevel_t) msg->info.level;
19 spinlock_acquire(&global_syslog_lock);
20
21 if (level != MOS_LOG_UNSET)
22 {
23 lprintk(loglevel: level, format: "\r\n");
24 if (feat)
25 lprintk(loglevel: level, format: "%-10s | ", feat->name);
26
27#if MOS_CONFIG(MOS_PRINTK_WITH_TIMESTAMP)
28 lprintk(level, "%-16lu | ", msg->timestamp);
29#endif
30
31#if MOS_CONFIG(MOS_PRINTK_WITH_DATETIME)
32 lprintk(level, "%s | ", (const char *) platform_get_datetime_str());
33#endif
34
35#if MOS_CONFIG(MOS_PRINTK_WITH_CPU_ID)
36 lprintk(level, "cpu %2d | ", msg->cpu_id);
37#endif
38
39#if MOS_CONFIG(MOS_PRINTK_WITH_FILENAME)
40 lprintk(loglevel: level, format: "%-15s | ", msg->info.source_location.filename);
41#endif
42
43#if MOS_CONFIG(MOS_PRINTK_WITH_THREAD_ID)
44 lprintk(level, "[t%d:%s]\t| ", msg->thread.tid, msg->thread.name);
45#endif
46 }
47
48 lprintk(loglevel: level, format: "%s", msg->message);
49
50 spinlock_release(&global_syslog_lock);
51}
52
53long do_syslog(loglevel_t level, const char *file, const char *func, int line, const debug_info_entry *feat, const char *fmt, ...)
54{
55 auto const thread = current_thread;
56 pb_syslog_message msg = {
57 .timestamp = platform_get_timestamp(),
58 .cpu_id = platform_current_cpu_id(),
59 };
60
61 msg.info.level = (syslog_level) level;
62 msg.info.featid = feat ? feat->id : 0;
63 msg.info.source_location.line = line;
64 strncpy(dest: msg.info.source_location.filename, src: file, n: sizeof(msg.info.source_location.filename));
65 strncpy(dest: msg.info.source_location.function, src: func, n: sizeof(msg.info.source_location.function));
66
67 if (thread)
68 {
69 msg.thread.tid = thread->tid;
70 msg.process.pid = thread->owner->pid;
71 strncpy(dest: msg.thread.name, src: thread->name.c_str(), n: sizeof(msg.thread.name));
72 strncpy(dest: msg.process.name, src: thread->owner->name.c_str(), n: sizeof(msg.process.name));
73 }
74
75 va_list args;
76 va_start(args, fmt);
77 vsnprintf(buf: msg.message, size: sizeof(msg.message), format: fmt, args);
78 va_end(args);
79
80 do_print_syslog(msg: &msg, feat);
81 return 0;
82}
83