blob: 05f6b7741059b7accdc40aba3efb1c5d1e4c7fdd [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 Marchi52a50fe2012-11-06 18:26:34 -020025#include "libkmod.h"
Lucas De Marchi92aad742012-11-06 18:04:09 -020026#include "kmod.h"
27
28static bool log_use_syslog;
Lucas De Marchi52a50fe2012-11-06 18:26:34 -020029static int log_priority = LOG_ERR;
Lucas De Marchi92aad742012-11-06 18:04:09 -020030
Lucas De Marchic8412732012-11-06 19:06:11 -020031static _always_inline_ const char *prio_to_str(int prio)
Lucas De Marchi92aad742012-11-06 18:04:09 -020032{
Lucas De Marchic8412732012-11-06 19:06:11 -020033 const char *prioname;
34 char buf[32];
Lucas De Marchi92aad742012-11-06 18:04:09 -020035
Lucas De Marchic8412732012-11-06 19:06:11 -020036 switch (prio) {
37 case LOG_CRIT:
38 prioname = "FATAL";
39 break;
40 case LOG_ERR:
41 prioname = "ERROR";
42 break;
43 case LOG_WARNING:
44 prioname = "WARNING";
45 break;
46 case LOG_NOTICE:
47 prioname = "NOTICE";
48 break;
49 case LOG_INFO:
50 prioname = "INFO";
51 break;
52 case LOG_DEBUG:
53 prioname = "DEBUG";
54 break;
55 default:
56 snprintf(buf, sizeof(buf), "LOG-%03d", prio);
57 prioname = buf;
58 }
59
60 return prioname;
Lucas De Marchi92aad742012-11-06 18:04:09 -020061}
62
Lucas De Marchi1958af82013-04-21 16:16:18 -030063_printf_format_(6, 0)
Lucas De Marchic8412732012-11-06 19:06:11 -020064static void log_kmod(void *data, int priority, const char *file, int line,
65 const char *fn, const char *format, va_list args)
Lucas De Marchi92aad742012-11-06 18:04:09 -020066{
67 const char *prioname = prio_to_str(priority);
68 char *str;
69
70 if (vasprintf(&str, format, args) < 0)
71 return;
72
73 if (log_use_syslog) {
74#ifdef ENABLE_DEBUG
75 syslog(priority, "%s: %s:%d %s() %s", prioname, file, line,
76 fn, str);
77#else
78 syslog(priority, "%s: %s", prioname, str);
79#endif
80 } else {
81#ifdef ENABLE_DEBUG
Lucas De Marchi7c04aee2012-11-06 19:20:09 -020082 fprintf(stderr, "%s: %s: %s:%d %s() %s",
83 program_invocation_short_name, prioname, file, line,
84 fn, str);
Lucas De Marchi92aad742012-11-06 18:04:09 -020085#else
Lucas De Marchi7c04aee2012-11-06 19:20:09 -020086 fprintf(stderr, "%s: %s: %s", program_invocation_short_name,
87 prioname, str);
Lucas De Marchi92aad742012-11-06 18:04:09 -020088#endif
89 }
90
91 free(str);
92 (void)data;
93}
Lucas De Marchic8412732012-11-06 19:06:11 -020094void log_open(bool use_syslog)
95{
96 log_use_syslog = use_syslog;
97
98 if (log_use_syslog)
Lucas De Marchi7c04aee2012-11-06 19:20:09 -020099 openlog(program_invocation_short_name, LOG_CONS, LOG_DAEMON);
Lucas De Marchic8412732012-11-06 19:06:11 -0200100}
101
102void log_close(void)
103{
104 if (log_use_syslog)
105 closelog();
106}
Lucas De Marchi52a50fe2012-11-06 18:26:34 -0200107
Lucas De Marchifcb0ce92012-11-06 19:01:59 -0200108void log_printf(int prio, const char *fmt, ...)
109{
110 const char *prioname;
111 char *msg;
112 va_list args;
113
114 if (prio > log_priority)
115 return;
116
117 va_start(args, fmt);
118 if (vasprintf(&msg, fmt, args) < 0)
119 msg = NULL;
120 va_end(args);
121 if (msg == NULL)
122 return;
123
124 prioname = prio_to_str(prio);
125
126 if (log_use_syslog)
127 syslog(prio, "%s: %s", prioname, msg);
128 else
Lucas De Marchi7c04aee2012-11-06 19:20:09 -0200129 fprintf(stderr, "%s: %s: %s", program_invocation_short_name,
130 prioname, msg);
Lucas De Marchifcb0ce92012-11-06 19:01:59 -0200131 free(msg);
132
133 if (prio <= LOG_CRIT)
134 exit(EXIT_FAILURE);
135}
136
Lucas De Marchi52a50fe2012-11-06 18:26:34 -0200137void log_setup_kmod_log(struct kmod_ctx *ctx, int priority)
138{
139 log_priority = priority;
140
141 kmod_set_log_priority(ctx, log_priority);
142 kmod_set_log_fn(ctx, log_kmod, NULL);
143}