source: mainline/uspace/srv/logger/logs.c@ 90dc458

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 90dc458 was 90dc458, checked in by Vojtech Horky <vojtechhorky@…>, 13 years ago

Create log files lazily

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2 * Copyright (c) 2012 Vojtech Horky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - 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 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup logger
30 * @{
31 */
32#include <assert.h>
33#include <malloc.h>
34#include <str.h>
35#include <stdio.h>
36#include <errno.h>
37#include "logger.h"
38
39
40static FIBRIL_MUTEX_INITIALIZE(log_list_guard);
41static LIST_INITIALIZE(log_list);
42
43
44static logger_log_t *find_log_by_name_and_parent_no_list_lock_and_acquire(const char *name, logger_log_t *parent)
45{
46 list_foreach(log_list, it) {
47 logger_log_t *log = list_get_instance(it, logger_log_t, link);
48 if ((parent == log->parent) && (str_cmp(log->name, name) == 0)) {
49 fibril_mutex_lock(&log->guard);
50 return log;
51 }
52 }
53
54 return NULL;
55}
56
57static int create_dest(const char *name, logger_dest_t **dest)
58{
59 logger_dest_t *result = malloc(sizeof(logger_dest_t));
60 if (result == NULL)
61 return ENOMEM;
62 int rc = asprintf(&result->filename, "/log/%s", name);
63 if (rc < 0) {
64 free(result);
65 return ENOMEM;
66 }
67 result->logfile = NULL;
68 fibril_mutex_initialize(&result->guard);
69 *dest = result;
70 return EOK;
71}
72
73int find_or_create_log_and_acquire(const char *name, sysarg_t parent_id, logger_log_t **log_out)
74{
75 int rc;
76 logger_log_t *result = NULL;
77 logger_log_t *parent = (logger_log_t *) parent_id;
78
79 fibril_mutex_lock(&log_list_guard);
80
81 result = find_log_by_name_and_parent_no_list_lock_and_acquire(name, parent);
82 if (result != NULL) {
83 rc = EOK;
84 goto leave;
85 }
86
87 result = calloc(1, sizeof(logger_log_t));
88 if (result == NULL) {
89 rc = ENOMEM;
90 goto leave;
91 }
92
93 result->logged_level = LOG_LEVEL_USE_DEFAULT;
94 result->name = str_dup(name);
95 if (parent == NULL) {
96 result->full_name = str_dup(name);
97 rc = create_dest(name, &result->dest);
98 if (rc != EOK)
99 goto error_result_allocated;
100 } else {
101 rc = asprintf(&result->full_name, "%s/%s",
102 parent->full_name, name);
103 if (rc < 0)
104 goto error_result_allocated;
105 result->dest = parent->dest;
106 }
107 result->parent = parent;
108 fibril_mutex_initialize(&result->guard);
109
110 link_initialize(&result->link);
111
112 fibril_mutex_lock(&result->guard);
113
114 list_append(&result->link, &log_list);
115
116
117leave:
118 fibril_mutex_unlock(&log_list_guard);
119
120 if (rc == EOK) {
121 assert(fibril_mutex_is_locked(&result->guard));
122 *log_out = result;
123 }
124
125 return rc;
126
127error_result_allocated:
128 free(result->name);
129 free(result->full_name);
130 free(result);
131
132 fibril_mutex_unlock(&log_list_guard);
133
134 return rc;
135}
136
137logger_log_t *find_log_by_name_and_acquire(const char *name)
138{
139 logger_log_t *result = NULL;
140
141 fibril_mutex_lock(&log_list_guard);
142 list_foreach(log_list, it) {
143 logger_log_t *log = list_get_instance(it, logger_log_t, link);
144 if (str_cmp(log->full_name, name) == 0) {
145 fibril_mutex_lock(&log->guard);
146 result = log;
147 break;
148 }
149 }
150 fibril_mutex_unlock(&log_list_guard);
151
152 return result;
153}
154
155logger_log_t *find_log_by_id_and_acquire(sysarg_t id)
156{
157 logger_log_t *result = NULL;
158
159 fibril_mutex_lock(&log_list_guard);
160 list_foreach(log_list, it) {
161 logger_log_t *log = list_get_instance(it, logger_log_t, link);
162 if ((sysarg_t) log == id) {
163 fibril_mutex_lock(&log->guard);
164 result = log;
165 break;
166 }
167 }
168 fibril_mutex_unlock(&log_list_guard);
169
170 return result;
171}
172
173static log_level_t get_actual_log_level(logger_log_t *log)
174{
175 /* Find recursively proper log level. */
176 if (log->logged_level == LOG_LEVEL_USE_DEFAULT) {
177 if (log->parent == NULL)
178 return get_default_logging_level();
179 else
180 return get_actual_log_level(log->parent);
181 }
182 return log->logged_level;
183}
184
185bool shall_log_message(logger_log_t *log, log_level_t level)
186{
187 fibril_mutex_lock(&log_list_guard);
188 bool result = level <= get_actual_log_level(log);
189 fibril_mutex_unlock(&log_list_guard);
190 return result;
191}
192
193void log_release(logger_log_t *log)
194{
195 assert(fibril_mutex_is_locked(&log->guard));
196 fibril_mutex_unlock(&log->guard);
197}
198
199void write_to_log(logger_log_t *log, log_level_t level, const char *message)
200{
201 assert(fibril_mutex_is_locked(&log->guard));
202 assert(log->dest != NULL);
203 fibril_mutex_lock(&log->dest->guard);
204 if (log->dest->logfile == NULL)
205 log->dest->logfile = fopen(log->dest->filename, "a");
206
207 if (log->dest->logfile != NULL) {
208 fprintf(log->dest->logfile, "[%s] %s: %s\n",
209 log->full_name, log_level_str(level),
210 (const char *) message);
211 fflush(log->dest->logfile);
212 }
213
214 fibril_mutex_unlock(&log->dest->guard);
215}
216
217/**
218 * @}
219 */
Note: See TracBrowser for help on using the repository browser.