blob: 21ef305a9651c96ac716201349159d8982bf5bd6 [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 Marchic8412732012-11-06 19:06:11 -020063static void log_kmod(void *data, int priority, const char *file, int line,
64 const char *fn, const char *format, va_list args)
Lucas De Marchi92aad742012-11-06 18:04:09 -020065{
66 const char *prioname = prio_to_str(priority);
67 char *str;
68
69 if (vasprintf(&str, format, args) < 0)
70 return;
71
72 if (log_use_syslog) {
73#ifdef ENABLE_DEBUG
74 syslog(priority, "%s: %s:%d %s() %s", prioname, file, line,
75 fn, str);
76#else
77 syslog(priority, "%s: %s", prioname, str);
78#endif
79 } else {
80#ifdef ENABLE_DEBUG
Lucas De Marchi7c04aee2012-11-06 19:20:09 -020081 fprintf(stderr, "%s: %s: %s:%d %s() %s",
82 program_invocation_short_name, prioname, file, line,
83 fn, str);
Lucas De Marchi92aad742012-11-06 18:04:09 -020084#else
Lucas De Marchi7c04aee2012-11-06 19:20:09 -020085 fprintf(stderr, "%s: %s: %s", program_invocation_short_name,
86 prioname, str);
Lucas De Marchi92aad742012-11-06 18:04:09 -020087#endif
88 }
89
90 free(str);
91 (void)data;
92}
Lucas De Marchic8412732012-11-06 19:06:11 -020093void log_open(bool use_syslog)
94{
95 log_use_syslog = use_syslog;
96
97 if (log_use_syslog)
Lucas De Marchi7c04aee2012-11-06 19:20:09 -020098 openlog(program_invocation_short_name, LOG_CONS, LOG_DAEMON);
Lucas De Marchic8412732012-11-06 19:06:11 -020099}
100
101void log_close(void)
102{
103 if (log_use_syslog)
104 closelog();
105}
Lucas De Marchi52a50fe2012-11-06 18:26:34 -0200106
Lucas De Marchifcb0ce92012-11-06 19:01:59 -0200107void log_printf(int prio, const char *fmt, ...)
108{
109 const char *prioname;
110 char *msg;
111 va_list args;
112
113 if (prio > log_priority)
114 return;
115
116 va_start(args, fmt);
117 if (vasprintf(&msg, fmt, args) < 0)
118 msg = NULL;
119 va_end(args);
120 if (msg == NULL)
121 return;
122
123 prioname = prio_to_str(prio);
124
125 if (log_use_syslog)
126 syslog(prio, "%s: %s", prioname, msg);
127 else
Lucas De Marchi7c04aee2012-11-06 19:20:09 -0200128 fprintf(stderr, "%s: %s: %s", program_invocation_short_name,
129 prioname, msg);
Lucas De Marchifcb0ce92012-11-06 19:01:59 -0200130 free(msg);
131
132 if (prio <= LOG_CRIT)
133 exit(EXIT_FAILURE);
134}
135
Lucas De Marchi52a50fe2012-11-06 18:26:34 -0200136void log_setup_kmod_log(struct kmod_ctx *ctx, int priority)
137{
138 log_priority = priority;
139
140 kmod_set_log_priority(ctx, log_priority);
141 kmod_set_log_fn(ctx, log_kmod, NULL);
142}