123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- #include <u.h>
- #include <libc.h>
- #include <venti.h>
- char *VtServerLog = "libventi/server";
- int ventilogging;
- #define log not_the_log_library_call
- static char Eremoved[] = "[removed]";
- enum
- { /* defaults */
- LogChunkSize = 8192,
- LogSize = 65536
- };
- static struct {
- QLock lk;
- VtLog *hash[1024];
- } vl;
- static uint
- hash(char *s)
- {
- uint h;
- uchar *p;
- h = 0;
- for(p=(uchar*)s; *p; p++)
- h = h*37 + *p;
- return h;
- }
- char**
- vtlognames(int *pn)
- {
- int i, nname, size;
- VtLog *l;
- char **s, *a, *e;
-
- qlock(&vl.lk);
- size = 0;
- nname = 0;
- for(i=0; i<nelem(vl.hash); i++)
- for(l=vl.hash[i]; l; l=l->next){
- nname++;
- size += strlen(l->name)+1;
- }
-
- s = vtmalloc(nname*sizeof(char*)+size);
- a = (char*)(s+nname);
- e = (char*)s+nname*sizeof(char*)+size;
- nname = 0;
- for(i=0; i<nelem(vl.hash); i++)
- for(l=vl.hash[i]; l; l=l->next){
- strcpy(a, l->name);
- s[nname++] = a;
- a += strlen(a)+1;
- }
- *pn = nname;
- assert(a == e);
- qunlock(&vl.lk);
- return s;
- }
- VtLog*
- vtlogopen(char *name, uint size)
- {
- uint h;
- int i, nc;
- char *p;
- VtLog *l, *last;
- if(!ventilogging)
- return nil;
- h = hash(name)%nelem(vl.hash);
- qlock(&vl.lk);
- last = nil;
- for(l=vl.hash[h]; l; last=l, l=l->next)
- if(strcmp(l->name, name) == 0){
- if(last){ /* move to front */
- last->next = l->next;
- l->next = vl.hash[h];
- vl.hash[h] = l;
- }
- l->ref++;
- qunlock(&vl.lk);
- return l;
- }
- if(size == 0){
- qunlock(&vl.lk);
- return nil;
- }
- /* allocate */
- nc = (size+LogChunkSize-1)/LogChunkSize;
- l = vtmalloc(sizeof *l + nc*(sizeof(*l->chunk)+LogChunkSize) + strlen(name)+1);
- memset(l, 0, sizeof *l);
- l->chunk = (VtLogChunk*)(l+1);
- l->nchunk = nc;
- l->w = l->chunk;
- p = (char*)(l->chunk+nc);
- for(i=0; i<nc; i++){
- l->chunk[i].p = p;
- l->chunk[i].wp = p;
- p += LogChunkSize;
- l->chunk[i].ep = p;
- }
- strcpy(p, name);
- l->name = p;
-
- /* insert */
- l->next = vl.hash[h];
- vl.hash[h] = l;
- l->ref++;
-
- l->ref++;
- qunlock(&vl.lk);
- return l;
- }
- void
- vtlogclose(VtLog *l)
- {
- if(l == nil)
- return;
- qlock(&vl.lk);
- if(--l->ref == 0){
- /* must not be in hash table */
- assert(l->name == Eremoved);
- free(l);
- }else
- assert(l->ref > 0);
- qunlock(&vl.lk);
- }
- void
- vtlogremove(char *name)
- {
- uint h;
- VtLog *last, *l;
- h = hash(name)%nelem(vl.hash);
- qlock(&vl.lk);
- last = nil;
- for(l=vl.hash[h]; l; last=l, l=l->next)
- if(strcmp(l->name, name) == 0){
- if(last)
- last->next = l->next;
- else
- vl.hash[h] = l->next;
- l->name = Eremoved;
- l->next = nil;
- qunlock(&vl.lk);
- vtlogclose(l);
- return;
- }
- qunlock(&vl.lk);
- }
- static int
- timefmt(Fmt *fmt)
- {
- static uvlong t0;
- uvlong t;
- Tm tm;
- if(fmt->flags&FmtSharp){
- if(t0 == 0)
- t0 = nsec();
- t = nsec()-t0;
- return fmtprint(fmt, "T+%d.%04d", (uint)(t/1000000000), (uint)(t%1000000000)/100000);
- }else{
- tm = *localtime(time(0));
- return fmtprint(fmt, "%04d/%02d%02d %02d:%02d:%02d",
- 1900+tm.year, tm.mon+1, tm.mday, tm.hour, tm.min, tm.sec);
- }
- }
- void
- vtlogvprint(VtLog *l, char *fmt, va_list arg)
- {
- int n;
- char *p;
- VtLogChunk *c;
- static int first = 1;
- if(l == nil)
- return;
-
- if(first){
- fmtinstall('T', timefmt);
- first = 0;
- }
-
-
- qlock(&l->lk);
- c = l->w;
- n = c->ep - c->wp;
- if(n < 512){
- c++;
- if(c == l->chunk+l->nchunk)
- c = l->chunk;
- c->wp = c->p;
- l->w = c;
- }
- p = vseprint(c->wp, c->ep, fmt, arg);
- if(p)
- c->wp = p;
- qunlock(&l->lk);
- }
- void
- vtlogprint(VtLog *l, char *fmt, ...)
- {
- va_list arg;
-
- if(l == nil)
- return;
-
- va_start(arg, fmt);
- vtlogvprint(l, fmt, arg);
- va_end(arg);
- }
- void
- vtlog(char *name, char *fmt, ...)
- {
- VtLog *l;
- va_list arg;
- l = vtlogopen(name, LogSize);
- if(l == nil)
- return;
- va_start(arg, fmt);
- vtlogvprint(l, fmt, arg);
- va_end(arg);
- vtlogclose(l);
- }
- void
- vtlogdump(int fd, VtLog *l)
- {
- int i;
- VtLogChunk *c;
- if(l == nil)
- return;
-
- c = l->w;
- for(i=0; i<l->nchunk; i++){
- if(++c == l->chunk+l->nchunk)
- c = l->chunk;
- write(fd, c->p, c->wp-c->p);
- }
- }
|