root/src/utils/noit_log.c

Revision e9e34e93fc6277f41f6f5165863408f7a66bcc21, 5.6 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 years ago)

only log to outlets if the parent is enabled. init op_ctx to -1 for posix ops

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  */
5
6 #include "noit_defines.h"
7 #include <stdio.h>
8 #include <fcntl.h>
9 #include <unistd.h>
10
11 #include "utils/noit_log.h"
12 #include "utils/noit_hash.h"
13
14 static noit_hash_table noit_loggers = NOIT_HASH_EMPTY;
15 noit_log_stream_t noit_stderr = NULL;
16 noit_log_stream_t noit_error = NULL;
17 noit_log_stream_t noit_debug = NULL;
18
19 static int
20 posix_logio_open(noit_log_stream_t ls) {
21   int fd;
22   fd = open(ls->path, O_CREAT|O_WRONLY|O_APPEND);
23   if(fd < 0) {
24     ls->op_ctx = NULL;
25     return -1;
26   }
27   ls->op_ctx = (void *)fd;
28   return 0;
29 }
30 static int
31 posix_logio_reopen(noit_log_stream_t ls) {
32   if(ls->path) {
33     int newfd, oldfd;
34     oldfd = (int)ls->op_ctx;
35     newfd = open(ls->path, O_CREAT|O_WRONLY|O_APPEND);
36     if(newfd >= 0) {
37       ls->op_ctx = (void *)newfd;
38       if(oldfd >= 0) close(oldfd);
39       return 0;
40     }
41   }
42   return -1;
43 }
44 static int
45 posix_logio_write(noit_log_stream_t ls, const void *buf, size_t len) {
46   int fd;
47   fd = (int)ls->op_ctx;
48   if(fd < 0) return -1;
49   return write(fd, buf, len);
50 }
51 static int
52 posix_logio_close(noit_log_stream_t ls) {
53   int fd;
54   fd = (int)ls->op_ctx;
55   return close(fd);
56 }
57 static logops_t posix_logio_ops = {
58   posix_logio_open,
59   posix_logio_reopen,
60   posix_logio_write,
61   posix_logio_close,
62 };
63
64 void
65 noit_log_init() {
66   noit_hash_init(&noit_loggers);
67   noit_stderr = noit_log_stream_new_on_fd("stderr", 2);
68   noit_error = noit_log_stream_new("error", NULL);
69   noit_debug = noit_log_stream_new("debug", NULL);
70 }
71
72 noit_log_stream_t
73 noit_log_stream_new_on_fd(const char *name, int fd) {
74   noit_log_stream_t ls;
75   ls = calloc(1, sizeof(*ls));
76   ls->name = strdup(name);
77   ls->ops = &posix_logio_ops;
78   ls->op_ctx = (void *)fd;
79   ls->enabled = 1;
80   if(noit_hash_store(&noit_loggers, ls->name, strlen(ls->name), ls) == 0) {
81     free(ls->name);
82     free(ls);
83     return NULL;
84   }
85   return ls;
86 }
87
88 noit_log_stream_t
89 noit_log_stream_new_on_file(const char *path) {
90   noit_log_stream_t ls;
91   ls = calloc(1, sizeof(*ls));
92   ls->path = strdup(path);
93   ls->ops = &posix_logio_ops;
94   if(ls->ops->openop(ls)) {
95     free(ls->path);
96     free(ls);
97     return NULL;
98   }
99   ls->name = strdup(ls->path);
100   ls->enabled = 1;
101   if(noit_hash_store(&noit_loggers, ls->name, strlen(ls->name), ls) == 0) {
102     free(ls->path);
103     free(ls->name);
104     free(ls);
105     return NULL;
106   }
107   return ls;
108 }
109
110 noit_log_stream_t
111 noit_log_stream_new(const char *name, logops_t *ops) {
112   noit_log_stream_t ls;
113   ls = calloc(1, sizeof(*ls));
114   ls->name = strdup(name);
115   ls->enabled = 1;
116   ls->ops = ops ? ops : &posix_logio_ops;
117   if(!ops) ls->op_ctx = (void *)-1;
118   if(noit_hash_store(&noit_loggers, ls->name, strlen(ls->name), ls) == 0) {
119     free(ls->name);
120     free(ls);
121     return NULL;
122   }
123   return ls;
124 }
125
126 noit_log_stream_t
127 noit_log_stream_find(const char *name) {
128   noit_log_stream_t ls;
129   if(noit_hash_retrieve(&noit_loggers, name, strlen(name), (void **)&ls)) {
130     return ls;
131   }
132   return NULL;
133 }
134
135 void
136 noit_log_stream_add_stream(noit_log_stream_t ls, noit_log_stream_t outlet) {
137   struct _noit_log_stream_outlet_list *newnode;
138   newnode = calloc(1, sizeof(*newnode));
139   newnode->outlet = outlet;
140   newnode->next = ls->outlets;
141   ls->outlets = newnode;
142 }
143
144 noit_log_stream_t
145 noit_log_stream_remove_stream(noit_log_stream_t ls, const char *name) {
146   noit_log_stream_t outlet;
147   struct _noit_log_stream_outlet_list *node, *tmp;
148   if(!ls->outlets) return NULL;
149   if(!strcmp(ls->outlets->outlet->name, name)) {
150     node = ls->outlets;
151     ls->outlets = node->next;
152     outlet = node->outlet;
153     free(node);
154     return outlet;
155   }
156   for(node = ls->outlets; node->next; node = node->next) {
157     if(!strcmp(node->next->outlet->name, name)) {
158       /* splice */
159       tmp = node->next;
160       node->next = tmp->next;
161       /* pluck */
162       outlet = tmp->outlet;
163       /* shed */
164       free(tmp);
165       /* return */
166       return outlet;
167     }
168   }
169   return NULL;
170 }
171
172 void noit_log_stream_reopen(noit_log_stream_t ls) {
173   struct _noit_log_stream_outlet_list *node;
174   ls->ops->reopenop(ls);
175   for(node = ls->outlets; node; node = node->next) {
176     noit_log_stream_reopen(node->outlet);
177   }
178 }
179
180 void
181 noit_log_stream_close(noit_log_stream_t ls) {
182   struct _noit_log_stream_outlet_list *node;
183   ls->ops->closeop(ls);
184   for(node = ls->outlets; node; node = node->next) {
185     noit_log_stream_close(node->outlet);
186   }
187 }
188
189 void
190 noit_log_stream_free(noit_log_stream_t ls) {
191   if(ls) {
192     struct _noit_log_stream_outlet_list *node;
193     if(ls->name) free(ls->name);
194     if(ls->path) free(ls->path);
195     while(ls->outlets) {
196       node = ls->outlets->next;
197       free(ls->outlets);
198       ls->outlets = node;
199     }
200     free(ls);
201   }
202 }
203
204 void
205 noit_vlog(noit_log_stream_t ls, struct timeval *now,
206           const char *file, int line,
207           const char *format, va_list arg) {
208   char buffer[4096];
209   struct _noit_log_stream_outlet_list *node;
210 #ifdef va_copy
211   va_list copy;
212 #endif
213
214   if(ls->enabled) {
215     int len;
216 #ifdef va_copy
217     va_copy(copy, arg);
218     len = vsnprintf(buffer, sizeof(buffer), format, copy);
219     va_end(copy);
220 #else
221     len = vsnprintf(buffer, sizeof(buffer), format, arg);
222 #endif
223     ls->ops->writeop(ls, buffer, len); /* Not much one can do about errors */
224
225     for(node = ls->outlets; node; node = node->next) {
226   #ifdef va_copy
227       va_copy(copy, arg);
228       noit_vlog(node->outlet, now, file, line, format, copy);
229       va_end(copy);
230   #else
231       noit_vlog(node->outlet, now, file, line, format, arg);
232   #endif
233     }
234   }
235 }
236
237 void
238 noit_log(noit_log_stream_t ls, struct timeval *now,
239          const char *file, int line, const char *format, ...) {
240   va_list arg;
241   va_start(arg, format);
242   noit_vlog(ls, now, file, line, format, arg);
243   va_end(arg);
244 }
245
Note: See TracBrowser for help on using the browser.