blob: 05ff96fc84d2cff24ddceb0e0f598b6e3752d3fb [file] [log] [blame]
Lucas De Marchi92aad742012-11-06 18:04:09 -02001/*
2 * kmod - log infrastructure
3 *
Lucas De Marchie6b0e492013-01-16 11:27:21 -02004 * Copyright (C) 2012-2013 ProFUSION embedded systems
Lucas De Marchi92aad742012-11-06 18:04:09 -02005 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
Lucas De Marchi7c04aee2012-11-06 19:20:09 -020020#include <errno.h>
Lucas De Marchi92aad742012-11-06 18:04:09 -020021#include <stdio.h>
22#include <stdlib.h>
23#include <syslog.h>
24
Lucas De Marchic2e42862014-10-03 01:41:42 -030025#include <libkmod.h>
26
Lucas De Marchi92aad742012-11-06 18:04:09 -020027#include "kmod.h"
28
29static bool log_use_syslog;
Lucas De Marchi52a50fe2012-11-06 18:26:34 -020030static int log_priority = LOG_ERR;
Lucas De Marchi92aad742012-11-06 18:04:09 -020031
Lucas De Marchic8412732012-11-06 19:06:11 -020032static _always_inline_ const char *prio_to_str(int prio)
Lucas De Marchi92aad742012-11-06 18:04:09 -020033{
Lucas De Marchic8412732012-11-06 19:06:11 -020034 const char *prioname;
35 char buf[32];
Lucas De Marchi92aad742012-11-06 18:04:09 -020036
Lucas De Marchic8412732012-11-06 19:06:11 -020037 switch (prio) {
38 case LOG_CRIT:
39 prioname = "FATAL";
40 break;
41 case LOG_ERR:
42 prioname = "ERROR";
43 break;
44 case LOG_WARNING:
45 prioname = "WARNING";
46 break;
47 case LOG_NOTICE:
48 prioname = "NOTICE";
49 break;
50 case LOG_INFO:
51 prioname = "INFO";
52 break;
53 case LOG_DEBUG:
54 prioname = "DEBUG";
55 break;
56 default:
57 snprintf(buf, sizeof(buf), "LOG-%03d", prio);
58 prioname = buf;
59 }
60
61 return prioname;
Lucas De Marchi92aad742012-11-06 18:04:09 -020062}
63
Lucas De Marchi1958af82013-04-21 16:16:18 -030064_printf_format_(6, 0)
Lucas De Marchic8412732012-11-06 19:06:11 -020065static void log_kmod(void *data, int priority, const char *file, int line,
66 const char *fn, const char *format, va_list args)
Lucas De Marchi92aad742012-11-06 18:04:09 -020067{
68 const char *prioname = prio_to_str(priority);
69 char *str;
70
71 if (vasprintf(&str, format, args) < 0)
72 return;
73
74 if (log_use_syslog) {
75#ifdef ENABLE_DEBUG
76 syslog(priority, "%s: %s:%d %s() %s", prioname, file, line,
77 fn, str);
78#else
79 syslog(priority, "%s: %s", prioname, str);
80#endif
81 } else {
82#ifdef ENABLE_DEBUG
Lucas De Marchi7c04aee2012-11-06 19:20:09 -020083 fprintf(stderr, "%s: %s: %s:%d %s() %s",
84 program_invocation_short_name, prioname, file, line,
85 fn, str);
Lucas De Marchi92aad742012-11-06 18:04:09 -020086#else
Lucas De Marchi7c04aee2012-11-06 19:20:09 -020087 fprintf(stderr, "%s: %s: %s", program_invocation_short_name,
88 prioname, str);
Lucas De Marchi92aad742012-11-06 18:04:09 -020089#endif
90 }
91
92 free(str);
93 (void)data;
94}
Lucas De Marchic8412732012-11-06 19:06:11 -020095void log_open(bool use_syslog)
96{
97 log_use_syslog = use_syslog;
98
99 if (log_use_syslog)
Lucas De Marchi7c04aee2012-11-06 19:20:09 -0200100 openlog(program_invocation_short_name, LOG_CONS, LOG_DAEMON);
Lucas De Marchic8412732012-11-06 19:06:11 -0200101}
102
103void log_close(void)
104{
105 if (log_use_syslog)
106 closelog();
107}
Lucas De Marchi52a50fe2012-11-06 18:26:34 -0200108
Lucas De Marchifcb0ce92012-11-06 19:01:59 -0200109void log_printf(int prio, const char *fmt, ...)
110{
111 const char *prioname;
112 char *msg;
113 va_list args;
114
115 if (prio > log_priority)
116 return;
117
118 va_start(args, fmt);
119 if (vasprintf(&msg, fmt, args) < 0)
120 msg = NULL;
121 va_end(args);
122 if (msg == NULL)
123 return;
124
125 prioname = prio_to_str(prio);
126
127 if (log_use_syslog)
128 syslog(prio, "%s: %s", prioname, msg);
129 else
Lucas De Marchi7c04aee2012-11-06 19:20:09 -0200130 fprintf(stderr, "%s: %s: %s", program_invocation_short_name,
131 prioname, msg);
Lucas De Marchifcb0ce92012-11-06 19:01:59 -0200132 free(msg);
133
134 if (prio <= LOG_CRIT)
135 exit(EXIT_FAILURE);
136}
137
Lucas De Marchi52a50fe2012-11-06 18:26:34 -0200138void log_setup_kmod_log(struct kmod_ctx *ctx, int priority)
139{
140 log_priority = priority;
141
142 kmod_set_log_priority(ctx, log_priority);
143 kmod_set_log_fn(ctx, log_kmod, NULL);
144}