root/src/utils/noit_log.c

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

more work -- this doesn't do much except add plumbing

  • 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
17 void
18 noit_log_init() {
19   noit_hash_init(&noit_loggers);
20   noit_stderr = noit_log_stream_new_on_fd("stderr", 2);
21 }
22
23 noit_log_stream_t
24 noit_log_stream_new_on_fd(const char *name, int fd) {
25   noit_log_stream_t ls;
26   ls = calloc(1, sizeof(*ls));
27   ls->name = strdup(name);
28   ls->fd = fd;
29   ls->enabled = 1;
30   if(noit_hash_store(&noit_loggers, ls->name, strlen(ls->name), ls) == 0) {
31     free(ls->name);
32     free(ls);
33     return NULL;
34   }
35   return ls;
36 }
37
38 noit_log_stream_t
39 noit_log_stream_new_on_file(const char *path) {
40   noit_log_stream_t ls;
41   ls = calloc(1, sizeof(*ls));
42   ls->path = strdup(path);
43   ls->fd = open(ls->path, O_CREAT|O_WRONLY|O_APPEND);
44   if(ls->fd < 0) {
45     free(ls->path);
46     free(ls);
47     return NULL;
48   }
49   ls->name = strdup(ls->path);
50   ls->enabled = 1;
51   if(noit_hash_store(&noit_loggers, ls->name, strlen(ls->name), ls) == 0) {
52     free(ls->path);
53     free(ls->name);
54     free(ls);
55     return NULL;
56   }
57   return ls;
58 }
59
60 noit_log_stream_t
61 noit_log_stream_new(const char *name) {
62   noit_log_stream_t ls;
63   ls = calloc(1, sizeof(*ls));
64   ls->name = strdup(name);
65   ls->fd = -1;
66   ls->enabled = 1;
67   if(noit_hash_store(&noit_loggers, ls->name, strlen(ls->name), ls) == 0) {
68     free(ls->name);
69     free(ls);
70     return NULL;
71   }
72   return ls;
73 }
74
75 noit_log_stream_t
76 noit_log_stream_find(const char *name) {
77   noit_log_stream_t ls;
78   if(noit_hash_retrieve(&noit_loggers, name, strlen(name), (void **)&ls)) {
79     return ls;
80   }
81   return NULL;
82 }
83
84 void
85 noit_log_stream_add_stream(noit_log_stream_t ls, noit_log_stream_t outlet) {
86   struct _noit_log_stream_outlet_list *newnode;
87   newnode = calloc(1, sizeof(*newnode));
88   newnode->outlet = outlet;
89   newnode->next = ls->outlets;
90   ls->outlets = newnode;
91 }
92
93 noit_log_stream_t
94 noit_log_stream_remove_stream(noit_log_stream_t ls, const char *name) {
95   noit_log_stream_t outlet;
96   struct _noit_log_stream_outlet_list *node, *tmp;
97   if(!ls->outlets) return NULL;
98   if(!strcmp(ls->outlets->outlet->name, name)) {
99     node = ls->outlets;
100     ls->outlets = node->next;
101     outlet = node->outlet;
102     free(node);
103     return outlet;
104   }
105   for(node = ls->outlets; node->next; node = node->next) {
106     if(!strcmp(node->next->outlet->name, name)) {
107       /* splice */
108       tmp = node->next;
109       node->next = tmp->next;
110       /* pluck */
111       outlet = tmp->outlet;
112       /* shed */
113       free(tmp);
114       /* return */
115       return outlet;
116     }
117   }
118   return NULL;
119 }
120
121 void noit_log_stream_reopen(noit_log_stream_t ls) {
122   struct _noit_log_stream_outlet_list *node;
123   if(ls->path) {
124     int newfd, oldfd;
125     oldfd = ls->fd;
126     newfd = open(ls->path, O_CREAT|O_WRONLY|O_APPEND);
127     if(newfd >= 0) {
128       ls->fd = newfd;
129       if(oldfd >= 0) close(oldfd);
130     }
131   }
132   for(node = ls->outlets; node; node = node->next) {
133     noit_log_stream_reopen(node->outlet);
134   }
135 }
136
137 void
138 noit_log_stream_close(noit_log_stream_t ls) {
139   struct _noit_log_stream_outlet_list *node;
140   if(ls->fd >= 0) {
141     int oldfd;
142     oldfd = ls->fd;
143     ls->fd = -1;
144     close(oldfd);
145   }
146   for(node = ls->outlets; node; node = node->next) {
147     noit_log_stream_close(node->outlet);
148   }
149 }
150
151 void
152 noit_log_stream_free(noit_log_stream_t ls) {
153   if(ls) {
154     struct _noit_log_stream_outlet_list *node;
155     if(ls->name) free(ls->name);
156     if(ls->path) free(ls->path);
157     while(ls->outlets) {
158       node = ls->outlets->next;
159       free(ls->outlets);
160       ls->outlets = node;
161     }
162     free(ls);
163   }
164 }
165
166 void
167 noit_vlog(noit_log_stream_t ls, struct timeval *now,
168           const char *format, va_list arg) {
169   char buffer[4096];
170   struct _noit_log_stream_outlet_list *node;
171 #ifdef va_copy
172   va_list copy;
173 #endif
174
175   if(ls->fd >= 0) {
176     int len;
177 #ifdef va_copy
178     va_copy(copy, arg);
179     len = vsnprintf(buffer, sizeof(buffer), format, copy);
180     va_end(copy);
181 #else
182     len = vsnprintf(buffer, sizeof(buffer), format, arg);
183 #endif
184     write(ls->fd, buffer, len); /* Not much one can do about errors */
185   }
186
187   for(node = ls->outlets; node; node = node->next) {
188 #ifdef va_copy
189     va_copy(copy, arg);
190     noit_vlog(node->outlet, now, format, copy);
191     va_end(copy);
192 #else
193     noit_vlog(node->outlet, now, format, arg);
194 #endif
195   }
196 }
197
198 void
199 noit_log(noit_log_stream_t ls, struct timeval *now, const char *format, ...) {
200   va_list arg;
201   va_start(arg, format);
202   noit_vlog(ls, now, format, arg);
203   va_end(arg);
204 }
205
Note: See TracBrowser for help on using the browser.