agoo 2.5.5 → 2.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of agoo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +1 -1
- data/ext/agoo/agoo.c +4 -3
- data/ext/agoo/atomic.h +120 -0
- data/ext/agoo/bind.c +52 -52
- data/ext/agoo/bind.h +13 -13
- data/ext/agoo/con.c +499 -481
- data/ext/agoo/con.h +47 -39
- data/ext/agoo/debug.c +42 -42
- data/ext/agoo/debug.h +1 -1
- data/ext/agoo/doc.c +17 -17
- data/ext/agoo/doc.h +12 -12
- data/ext/agoo/err.c +18 -18
- data/ext/agoo/err.h +27 -27
- data/ext/agoo/error_stream.c +9 -9
- data/ext/agoo/extconf.rb +3 -0
- data/ext/agoo/gqlintro.c +43 -43
- data/ext/agoo/gqlintro.h +1 -1
- data/ext/agoo/gqlvalue.c +131 -131
- data/ext/agoo/gqlvalue.h +32 -32
- data/ext/agoo/graphql.c +158 -158
- data/ext/agoo/graphql.h +34 -33
- data/ext/agoo/hook.c +15 -14
- data/ext/agoo/hook.h +18 -14
- data/ext/agoo/http.c +14 -14
- data/ext/agoo/http.h +4 -4
- data/ext/agoo/kinds.h +5 -5
- data/ext/agoo/log.c +232 -224
- data/ext/agoo/log.h +93 -93
- data/ext/agoo/method.h +17 -17
- data/ext/agoo/page.c +88 -86
- data/ext/agoo/page.h +21 -21
- data/ext/agoo/pub.c +36 -36
- data/ext/agoo/pub.h +23 -23
- data/ext/agoo/queue.c +37 -38
- data/ext/agoo/queue.h +20 -19
- data/ext/agoo/rack_logger.c +13 -13
- data/ext/agoo/ready.c +357 -0
- data/ext/agoo/ready.h +41 -0
- data/ext/agoo/req.c +11 -11
- data/ext/agoo/req.h +30 -31
- data/ext/agoo/request.c +46 -46
- data/ext/agoo/request.h +2 -2
- data/ext/agoo/res.c +40 -18
- data/ext/agoo/res.h +14 -14
- data/ext/agoo/response.c +6 -6
- data/ext/agoo/response.h +9 -9
- data/ext/agoo/rhook.c +3 -3
- data/ext/agoo/rhook.h +1 -1
- data/ext/agoo/rlog.c +47 -42
- data/ext/agoo/rlog.h +0 -1
- data/ext/agoo/rresponse.c +33 -33
- data/ext/agoo/rresponse.h +1 -1
- data/ext/agoo/rserver.c +184 -175
- data/ext/agoo/rserver.h +2 -2
- data/ext/agoo/rupgraded.c +41 -41
- data/ext/agoo/rupgraded.h +3 -3
- data/ext/agoo/sdl.c +80 -80
- data/ext/agoo/sdl.h +1 -1
- data/ext/agoo/seg.h +2 -2
- data/ext/agoo/server.c +143 -117
- data/ext/agoo/server.h +43 -42
- data/ext/agoo/sse.c +7 -7
- data/ext/agoo/sse.h +4 -4
- data/ext/agoo/subject.c +5 -5
- data/ext/agoo/subject.h +6 -6
- data/ext/agoo/text.c +21 -21
- data/ext/agoo/text.h +14 -13
- data/ext/agoo/upgraded.c +41 -40
- data/ext/agoo/upgraded.h +41 -40
- data/ext/agoo/websocket.c +42 -42
- data/ext/agoo/websocket.h +16 -16
- data/lib/agoo/version.rb +1 -1
- data/test/static_test.rb +2 -0
- metadata +5 -5
- data/ext/agoo/log_queue.h +0 -30
- data/ext/agoo/sub.c +0 -111
- data/ext/agoo/sub.h +0 -36
data/ext/agoo/graphql.h
CHANGED
@@ -21,13 +21,14 @@ typedef enum {
|
|
21
21
|
// NON_NULL
|
22
22
|
} gqlKind;
|
23
23
|
|
24
|
-
struct
|
25
|
-
struct
|
26
|
-
struct _gqlLink;
|
27
|
-
struct _gqlField;
|
28
|
-
struct _Req;
|
24
|
+
struct _agooCon;
|
25
|
+
struct _agooReq;
|
29
26
|
struct _gqlDirUse;
|
27
|
+
struct _gqlField;
|
28
|
+
struct _gqlLink;
|
30
29
|
struct _gqlLink;
|
30
|
+
struct _gqlType;
|
31
|
+
struct _gqlValue;
|
31
32
|
|
32
33
|
// Used for references to implemenation entities.
|
33
34
|
typedef void* gqlRef;
|
@@ -106,7 +107,7 @@ typedef struct _gqlDirUse {
|
|
106
107
|
typedef struct _gqlType {
|
107
108
|
const char *name;
|
108
109
|
const char *desc;
|
109
|
-
|
110
|
+
agooText (*to_json)(agooText text, struct _gqlValue *value, int indent, int depth);
|
110
111
|
gqlDirUse dir;
|
111
112
|
gqlKind kind;
|
112
113
|
bool locked; // set by app
|
@@ -123,21 +124,21 @@ typedef struct _gqlType {
|
|
123
124
|
gqlStrLink choices; // Enums
|
124
125
|
// Returns error code. Only for scalars.
|
125
126
|
struct {
|
126
|
-
int (*coerce)(
|
127
|
+
int (*coerce)(agooErr err, struct _gqlValue *src, struct _gqlType *type);
|
127
128
|
void (*destroy)(struct _gqlValue *value);
|
128
129
|
};
|
129
130
|
};
|
130
131
|
} *gqlType;
|
131
132
|
|
132
|
-
extern int gql_init(
|
133
|
+
extern int gql_init(agooErr err);
|
133
134
|
extern void gql_destroy(); // clear out all
|
134
135
|
|
135
|
-
extern gqlType gql_type_create(
|
136
|
-
extern gqlType gql_fragment_create(
|
137
|
-
extern gqlType gql_input_create(
|
138
|
-
extern gqlType gql_interface_create(
|
136
|
+
extern gqlType gql_type_create(agooErr err, const char *name, const char *desc, int dlen, bool locked, gqlType *interfaces);
|
137
|
+
extern gqlType gql_fragment_create(agooErr err, const char *name, const char *desc, int dlen, bool locked, gqlType on);
|
138
|
+
extern gqlType gql_input_create(agooErr err, const char *name, const char *desc, int dlen, bool locked);
|
139
|
+
extern gqlType gql_interface_create(agooErr err, const char *name, const char *desc, int dlen, bool locked);
|
139
140
|
|
140
|
-
extern gqlField gql_type_field(
|
141
|
+
extern gqlField gql_type_field(agooErr err,
|
141
142
|
gqlType type,
|
142
143
|
const char *name,
|
143
144
|
gqlType return_type,
|
@@ -147,7 +148,7 @@ extern gqlField gql_type_field(Err err,
|
|
147
148
|
bool not_empty,
|
148
149
|
gqlResolveFunc resolve);
|
149
150
|
|
150
|
-
extern gqlArg gql_field_arg(
|
151
|
+
extern gqlArg gql_field_arg(agooErr err,
|
151
152
|
gqlField field,
|
152
153
|
const char *name,
|
153
154
|
gqlType type,
|
@@ -158,11 +159,11 @@ extern gqlArg gql_field_arg(Err err,
|
|
158
159
|
// TBD maybe create then add fields
|
159
160
|
// TBD same with op? create then add args
|
160
161
|
|
161
|
-
extern gqlType gql_scalar_create(
|
162
|
+
extern gqlType gql_scalar_create(agooErr err, const char *name, const char *desc, int dlen, bool locked);
|
162
163
|
|
163
|
-
extern gqlDir gql_directive_create(
|
164
|
-
extern int gql_directive_on(
|
165
|
-
extern gqlArg gql_dir_arg(
|
164
|
+
extern gqlDir gql_directive_create(agooErr err, const char *name, const char *desc, int dlen, bool locked);
|
165
|
+
extern int gql_directive_on(agooErr err, gqlDir d, const char *on, int len);
|
166
|
+
extern gqlArg gql_dir_arg(agooErr err,
|
166
167
|
gqlDir dir,
|
167
168
|
const char *name,
|
168
169
|
const char *type_name,
|
@@ -172,27 +173,27 @@ extern gqlArg gql_dir_arg(Err err,
|
|
172
173
|
bool required);
|
173
174
|
extern gqlDir gql_directive_get(const char *name);
|
174
175
|
|
175
|
-
extern gqlType gql_union_create(
|
176
|
-
extern int gql_union_add(
|
176
|
+
extern gqlType gql_union_create(agooErr err, const char *name, const char *desc, int dlen, bool locked);
|
177
|
+
extern int gql_union_add(agooErr err, gqlType type, const char *name, int len);
|
177
178
|
|
178
|
-
extern gqlType gql_enum_create(
|
179
|
-
extern int gql_enum_add(
|
180
|
-
extern int gql_enum_append(
|
179
|
+
extern gqlType gql_enum_create(agooErr err, const char *name, const char *desc, int dlen, bool locked);
|
180
|
+
extern int gql_enum_add(agooErr err, gqlType type, const char *value, int len);
|
181
|
+
extern int gql_enum_append(agooErr err, gqlType type, const char *value, int len);
|
181
182
|
|
182
|
-
extern int gql_type_set(
|
183
|
+
extern int gql_type_set(agooErr err, gqlType type);
|
183
184
|
extern gqlType gql_type_get(const char *name);
|
184
185
|
extern void gql_type_destroy(gqlType type);
|
185
186
|
|
186
|
-
extern
|
187
|
-
extern
|
188
|
-
extern
|
187
|
+
extern agooText gql_type_sdl(agooText text, gqlType type, bool comments);
|
188
|
+
extern agooText gql_directive_sdl(agooText text, gqlDir dir, bool comments);
|
189
|
+
extern agooText gql_schema_sdl(agooText text, bool with_desc, bool all);
|
189
190
|
|
190
|
-
extern
|
191
|
-
extern
|
192
|
-
extern
|
193
|
-
extern
|
191
|
+
extern agooText gql_object_to_json(agooText text, struct _gqlValue *value, int indent, int depth);
|
192
|
+
extern agooText gql_object_to_graphql(agooText text, struct _gqlValue *value, int indent, int depth);
|
193
|
+
extern agooText gql_union_to_text(agooText text, struct _gqlValue *value, int indent, int depth);
|
194
|
+
extern agooText gql_enum_to_text(agooText text, struct _gqlValue *value, int indent, int depth);
|
194
195
|
|
195
|
-
extern void gql_dump_hook(struct
|
196
|
-
extern void gql_eval_hook(struct
|
196
|
+
extern void gql_dump_hook(struct _agooReq *req);
|
197
|
+
extern void gql_eval_hook(struct _agooReq *req);
|
197
198
|
|
198
199
|
#endif // AGOO_GRAPHQL_H
|
data/ext/agoo/hook.c
CHANGED
@@ -3,20 +3,21 @@
|
|
3
3
|
#include <stdlib.h>
|
4
4
|
#include <string.h>
|
5
5
|
|
6
|
+
#include "con.h"
|
6
7
|
#include "debug.h"
|
7
8
|
#include "hook.h"
|
8
9
|
#include "req.h"
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
agooHook
|
12
|
+
agoo_hook_create(agooMethod method, const char *pattern, void *handler, agooHookType type, agooQueue q) {
|
13
|
+
agooHook hook = (agooHook)malloc(sizeof(struct _agooHook));
|
13
14
|
|
14
15
|
if (NULL != hook) {
|
15
16
|
char *pat = NULL;
|
16
17
|
|
17
18
|
DEBUG_ALLOC(mem_hook, hook);
|
18
19
|
if (NULL == pattern) {
|
19
|
-
if (
|
20
|
+
if (AGOO_NONE != method) {
|
20
21
|
pat = strdup("");
|
21
22
|
}
|
22
23
|
} else {
|
@@ -35,16 +36,16 @@ hook_create(Method method, const char *pattern, void *handler, HookType type, Qu
|
|
35
36
|
return hook;
|
36
37
|
}
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
39
|
+
agooHook
|
40
|
+
agoo_hook_func_create(agooMethod method, const char *pattern, void (*func)(agooReq req), agooQueue q) {
|
41
|
+
agooHook hook = (agooHook)malloc(sizeof(struct _agooHook));
|
41
42
|
|
42
43
|
if (NULL != hook) {
|
43
44
|
char *pat = NULL;
|
44
45
|
|
45
46
|
DEBUG_ALLOC(mem_hook, hook);
|
46
47
|
if (NULL == pattern) {
|
47
|
-
if (
|
48
|
+
if (AGOO_NONE != method) {
|
48
49
|
pat = strdup("");
|
49
50
|
}
|
50
51
|
} else {
|
@@ -64,7 +65,7 @@ hook_func_create(Method method, const char *pattern, void (*func)(Req req), Queu
|
|
64
65
|
}
|
65
66
|
|
66
67
|
void
|
67
|
-
|
68
|
+
agoo_hook_destroy(agooHook hook) {
|
68
69
|
if (NULL != hook->pattern) {
|
69
70
|
DEBUG_FREE(mem_hook_pattern, hook->pattern);
|
70
71
|
free(hook->pattern);
|
@@ -74,7 +75,7 @@ hook_destroy(Hook hook) {
|
|
74
75
|
}
|
75
76
|
|
76
77
|
bool
|
77
|
-
|
78
|
+
agoo_hook_match(agooHook hook, agooMethod method, const agooSeg path) {
|
78
79
|
const char *pat = hook->pattern;
|
79
80
|
char *p = path->start;
|
80
81
|
char *end = path->end;
|
@@ -82,7 +83,7 @@ hook_match(Hook hook, Method method, const Seg path) {
|
|
82
83
|
if (1 < end - p && '/' == *(end - 1)) {
|
83
84
|
end--;
|
84
85
|
}
|
85
|
-
if (method != hook->method &&
|
86
|
+
if (method != hook->method && AGOO_ALL != hook->method) {
|
86
87
|
return false;
|
87
88
|
}
|
88
89
|
for (; '\0' != *pat && p < end; pat++) {
|
@@ -101,10 +102,10 @@ hook_match(Hook hook, Method method, const Seg path) {
|
|
101
102
|
return '\0' == *pat && p == end;
|
102
103
|
}
|
103
104
|
|
104
|
-
|
105
|
-
|
105
|
+
agooHook
|
106
|
+
agoo_hook_find(agooHook hook, agooMethod method, const agooSeg path) {
|
106
107
|
for (; NULL != hook; hook = hook->next) {
|
107
|
-
if (
|
108
|
+
if (agoo_hook_match(hook, method, path)) {
|
108
109
|
return hook;
|
109
110
|
}
|
110
111
|
}
|
data/ext/agoo/hook.h
CHANGED
@@ -9,7 +9,8 @@
|
|
9
9
|
#include "queue.h"
|
10
10
|
#include "seg.h"
|
11
11
|
|
12
|
-
struct
|
12
|
+
struct _agooCon;
|
13
|
+
struct _agooReq;
|
13
14
|
|
14
15
|
typedef enum {
|
15
16
|
NO_HOOK = '\0',
|
@@ -19,26 +20,29 @@ typedef enum {
|
|
19
20
|
PUSH_HOOK = 'P',
|
20
21
|
FUNC_HOOK = 'F',
|
21
22
|
FAST_HOOK = 'O', // for OpO
|
22
|
-
}
|
23
|
+
} agooHookType;
|
23
24
|
|
24
|
-
typedef struct
|
25
|
-
struct
|
26
|
-
|
25
|
+
typedef struct _agooHook {
|
26
|
+
struct _agooHook *next;
|
27
|
+
agooMethod method;
|
27
28
|
char *pattern;
|
28
|
-
|
29
|
+
agooHookType type;
|
29
30
|
union {
|
30
31
|
void *handler;
|
31
|
-
void (*func)(struct
|
32
|
+
void (*func)(struct _agooReq *req);
|
32
33
|
};
|
33
|
-
|
34
|
+
agooQueue queue;
|
34
35
|
bool no_queue;
|
35
|
-
} *
|
36
|
+
} *agooHook;
|
36
37
|
|
37
|
-
extern
|
38
|
-
extern
|
39
|
-
|
38
|
+
extern agooHook agoo_hook_create(agooMethod method, const char *pattern, void *handler, agooHookType type, agooQueue q);
|
39
|
+
extern agooHook agoo_hook_func_create(agooMethod method,
|
40
|
+
const char *pattern,
|
41
|
+
void (*func)(struct _agooReq *req),
|
42
|
+
agooQueue q);
|
43
|
+
extern void agoo_hook_destroy(agooHook hook);
|
40
44
|
|
41
|
-
extern bool
|
42
|
-
extern
|
45
|
+
extern bool agoo_hook_match(agooHook hook, agooMethod method, const agooSeg seg);
|
46
|
+
extern agooHook agoo_hook_find(agooHook hook, agooMethod method, const agooSeg seg);
|
43
47
|
|
44
48
|
#endif // AGOO_HOOK_H
|
data/ext/agoo/http.c
CHANGED
@@ -11,18 +11,18 @@
|
|
11
11
|
#define BUCKET_MASK 1023
|
12
12
|
#define MAX_KEY_UNIQ 9
|
13
13
|
|
14
|
-
typedef struct
|
15
|
-
struct
|
14
|
+
typedef struct _slot {
|
15
|
+
struct _slot *next;
|
16
16
|
const char *key;
|
17
17
|
uint64_t hash;
|
18
18
|
int klen;
|
19
19
|
} *Slot;
|
20
20
|
|
21
|
-
typedef struct
|
21
|
+
typedef struct _cache {
|
22
22
|
Slot buckets[BUCKET_SIZE];
|
23
23
|
} *Cache;
|
24
24
|
|
25
|
-
struct
|
25
|
+
struct _cache key_cache;
|
26
26
|
|
27
27
|
// The rack spec indicates the characters (),/:;<=>?@[]{} are invalid which
|
28
28
|
// clearly is not consisten with RFC7230 so stick with the RFC.
|
@@ -469,7 +469,7 @@ key_set(const char *key) {
|
|
469
469
|
Slot *bucket = get_bucketp(h);
|
470
470
|
Slot s;
|
471
471
|
|
472
|
-
if (NULL != (s = (Slot)malloc(sizeof(struct
|
472
|
+
if (NULL != (s = (Slot)malloc(sizeof(struct _slot)))) {
|
473
473
|
DEBUG_ALLOC(mem_http_slot, s)
|
474
474
|
s->hash = h;
|
475
475
|
s->klen = len;
|
@@ -480,17 +480,17 @@ key_set(const char *key) {
|
|
480
480
|
}
|
481
481
|
|
482
482
|
void
|
483
|
-
|
483
|
+
agoo_http_init() {
|
484
484
|
const char **kp = header_keys;
|
485
485
|
|
486
|
-
memset(&key_cache, 0, sizeof(struct
|
486
|
+
memset(&key_cache, 0, sizeof(struct _cache));
|
487
487
|
for (; NULL != *kp; kp++) {
|
488
488
|
key_set(*kp);
|
489
489
|
}
|
490
490
|
}
|
491
491
|
|
492
492
|
void
|
493
|
-
|
493
|
+
agoo_http_cleanup() {
|
494
494
|
Slot *sp = key_cache.buckets;
|
495
495
|
Slot s;
|
496
496
|
Slot n;
|
@@ -507,7 +507,7 @@ http_cleanup() {
|
|
507
507
|
}
|
508
508
|
|
509
509
|
int
|
510
|
-
|
510
|
+
agoo_http_header_ok(agooErr err, const char *key, int klen, const char *value, int vlen) {
|
511
511
|
int len = klen;
|
512
512
|
int64_t h = calc_hash(key, &len);
|
513
513
|
Slot *bucket = get_bucketp(h);
|
@@ -530,26 +530,26 @@ http_header_ok(Err err, const char *key, int klen, const char *value, int vlen)
|
|
530
530
|
strncpy(buf, key, klen);
|
531
531
|
buf[klen] = '\0';
|
532
532
|
|
533
|
-
return
|
533
|
+
return agoo_err_set(err, AGOO_ERR_ARG, "%s is not a valid HTTP header key.", buf);
|
534
534
|
}
|
535
535
|
// Now check the value.
|
536
536
|
found = false; // reuse as indicator for in a quoted string
|
537
537
|
for (; 0 < vlen; vlen--, value++) {
|
538
538
|
if ('o' != header_value_chars[(uint8_t)*value]) {
|
539
|
-
return
|
539
|
+
return agoo_err_set(err, AGOO_ERR_ARG, "%02x is not a valid HTTP header value character.", *value);
|
540
540
|
}
|
541
541
|
if ('"' == *value) {
|
542
542
|
found = !found;
|
543
543
|
}
|
544
544
|
}
|
545
545
|
if (found) {
|
546
|
-
return
|
546
|
+
return agoo_err_set(err, AGOO_ERR_ARG, "HTTP header has unmatched quote.");
|
547
547
|
}
|
548
|
-
return
|
548
|
+
return AGOO_ERR_OK;
|
549
549
|
}
|
550
550
|
|
551
551
|
const char*
|
552
|
-
|
552
|
+
agoo_http_code_message(int code) {
|
553
553
|
const char *msg = "";
|
554
554
|
|
555
555
|
switch (code) {
|
data/ext/agoo/http.h
CHANGED
@@ -7,11 +7,11 @@
|
|
7
7
|
|
8
8
|
#include "err.h"
|
9
9
|
|
10
|
-
extern void
|
11
|
-
extern void
|
10
|
+
extern void agoo_http_init();
|
11
|
+
extern void agoo_http_cleanup();
|
12
12
|
|
13
|
-
extern int
|
13
|
+
extern int agoo_http_header_ok(agooErr err, const char *key, int klen, const char *value, int vlen);
|
14
14
|
|
15
|
-
extern const char*
|
15
|
+
extern const char* agoo_http_code_message(int code);
|
16
16
|
|
17
17
|
#endif // AGOO_HTTP_H
|
data/ext/agoo/kinds.h
CHANGED
@@ -4,10 +4,10 @@
|
|
4
4
|
#define AGOO_KINDS_H
|
5
5
|
|
6
6
|
typedef enum {
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
}
|
7
|
+
AGOO_CON_ANY = '\0',
|
8
|
+
AGOO_CON_HTTP = 'H',
|
9
|
+
AGOO_CON_WS = 'W',
|
10
|
+
AGOO_CON_SSE = 'S',
|
11
|
+
} agooConKind;
|
12
12
|
|
13
13
|
#endif // AGOO_KINDS_H
|
data/ext/agoo/log.c
CHANGED
@@ -25,7 +25,7 @@
|
|
25
25
|
#define RESET_COLOR "\033[0m"
|
26
26
|
#define RESET_SIZE 4
|
27
27
|
|
28
|
-
static struct
|
28
|
+
static struct _agooColor colors[] = {
|
29
29
|
{ .name = "black", .ansi = "\033[30;1m" },
|
30
30
|
{ .name = "red", .ansi = "\033[31;1m" },
|
31
31
|
{ .name = "green", .ansi = "\033[32;1m" },
|
@@ -46,22 +46,22 @@ static struct _Color colors[] = {
|
|
46
46
|
|
47
47
|
static const char level_chars[] = { 'F', 'E', 'W', 'I', 'D', '?' };
|
48
48
|
|
49
|
-
struct
|
50
|
-
struct
|
51
|
-
struct
|
52
|
-
struct
|
53
|
-
struct
|
54
|
-
struct
|
55
|
-
struct
|
56
|
-
struct
|
57
|
-
struct
|
58
|
-
struct
|
59
|
-
struct
|
60
|
-
|
61
|
-
|
49
|
+
struct _agooLog agoo_log = {NULL};
|
50
|
+
struct _agooLogCat agoo_fatal_cat;
|
51
|
+
struct _agooLogCat agoo_error_cat;
|
52
|
+
struct _agooLogCat agoo_warn_cat;
|
53
|
+
struct _agooLogCat agoo_info_cat;
|
54
|
+
struct _agooLogCat agoo_debug_cat;
|
55
|
+
struct _agooLogCat agoo_con_cat;
|
56
|
+
struct _agooLogCat agoo_req_cat;
|
57
|
+
struct _agooLogCat agoo_resp_cat;
|
58
|
+
struct _agooLogCat agoo_eval_cat;
|
59
|
+
struct _agooLogCat agoo_push_cat;
|
60
|
+
|
61
|
+
agooColor
|
62
62
|
find_color(const char *name) {
|
63
63
|
if (NULL != name) {
|
64
|
-
for (
|
64
|
+
for (agooColor c = colors; NULL != c->name; c++) {
|
65
65
|
if (0 == strcasecmp(c->name, name)) {
|
66
66
|
return c;
|
67
67
|
}
|
@@ -71,79 +71,80 @@ find_color(const char *name) {
|
|
71
71
|
}
|
72
72
|
|
73
73
|
static bool
|
74
|
-
|
75
|
-
|
76
|
-
|
74
|
+
agoo_log_queue_empty() {
|
75
|
+
agooLogEntry head = atomic_load(&agoo_log.head);
|
76
|
+
agooLogEntry next = head + 1;
|
77
77
|
|
78
|
-
if (
|
79
|
-
next =
|
78
|
+
if (agoo_log.end <= next) {
|
79
|
+
next = agoo_log.q;
|
80
80
|
}
|
81
|
-
if (!head->ready &&
|
81
|
+
if (!head->ready && atomic_load(&agoo_log.tail) == next) {
|
82
82
|
return true;
|
83
83
|
}
|
84
84
|
return false;
|
85
85
|
}
|
86
86
|
|
87
87
|
static int
|
88
|
-
|
89
|
-
if (0 ==
|
88
|
+
agoo_log_listen() {
|
89
|
+
if (0 == agoo_log.rsock) {
|
90
90
|
int fd[2];
|
91
91
|
|
92
92
|
if (0 == pipe(fd)) {
|
93
93
|
fcntl(fd[0], F_SETFL, O_NONBLOCK);
|
94
94
|
fcntl(fd[1], F_SETFL, O_NONBLOCK);
|
95
|
-
|
96
|
-
|
95
|
+
agoo_log.rsock = fd[0];
|
96
|
+
agoo_log.wsock = fd[1];
|
97
97
|
}
|
98
98
|
}
|
99
|
-
atomic_store(&
|
99
|
+
atomic_store(&agoo_log.wait_state, WAITING);
|
100
100
|
|
101
|
-
return
|
101
|
+
return agoo_log.rsock;
|
102
102
|
}
|
103
103
|
|
104
104
|
static void
|
105
|
-
|
105
|
+
agoo_log_release() {
|
106
106
|
char buf[8];
|
107
107
|
|
108
108
|
// clear pipe
|
109
|
-
while (0 < read(
|
109
|
+
while (0 < read(agoo_log.rsock, buf, sizeof(buf))) {
|
110
110
|
}
|
111
|
-
atomic_store(&
|
111
|
+
atomic_store(&agoo_log.wait_state, NOT_WAITING);
|
112
112
|
}
|
113
113
|
|
114
|
-
static
|
115
|
-
|
116
|
-
|
117
|
-
|
114
|
+
static agooLogEntry
|
115
|
+
agoo_log_queue_pop(double timeout) {
|
116
|
+
agooLogEntry e = atomic_load(&agoo_log.head);
|
117
|
+
agooLogEntry next;
|
118
|
+
|
118
119
|
if (e->ready) {
|
119
120
|
return e;
|
120
121
|
}
|
121
|
-
next =
|
122
|
-
if (
|
123
|
-
next =
|
122
|
+
next = (agooLogEntry)atomic_load(&agoo_log.head) + 1;
|
123
|
+
if (agoo_log.end <= next) {
|
124
|
+
next = agoo_log.q;
|
124
125
|
}
|
125
126
|
// If the next is the tail then wait for something to be appended.
|
126
|
-
for (int cnt = (int)(timeout / (double)WAIT_MSECS * 1000.0); atomic_load(&
|
127
|
+
for (int cnt = (int)(timeout / (double)WAIT_MSECS * 1000.0); atomic_load(&agoo_log.tail) == next; cnt--) {
|
127
128
|
struct pollfd pa;
|
128
129
|
|
129
130
|
if (cnt <= 0) {
|
130
131
|
return NULL;
|
131
132
|
}
|
132
|
-
pa.fd =
|
133
|
+
pa.fd = agoo_log_listen();
|
133
134
|
pa.events = POLLIN;
|
134
135
|
pa.revents = 0;
|
135
136
|
if (0 < poll(&pa, 1, WAIT_MSECS)) {
|
136
|
-
|
137
|
+
agoo_log_release();
|
137
138
|
}
|
138
139
|
}
|
139
|
-
atomic_store(&
|
140
|
+
atomic_store(&agoo_log.head, next);
|
140
141
|
|
141
|
-
return
|
142
|
+
return next;
|
142
143
|
}
|
143
144
|
|
144
145
|
|
145
146
|
static int
|
146
|
-
jwrite(
|
147
|
+
jwrite(agooLogEntry e, FILE *file) {
|
147
148
|
// TBD make e->what JSON friendly
|
148
149
|
if (NULL == e->tidp && '\0' == *e->tid) {
|
149
150
|
return fprintf(file, "{\"when\":%lld.%09lld,\"where\":\"%s\",\"level\":%d,\"what\":\"%s\"}\n",
|
@@ -166,7 +167,7 @@ jwrite(LogEntry e, FILE *file) {
|
|
166
167
|
// I 2015/05/23 11:22:33.123456789 label: The contents of the what field.
|
167
168
|
// I 2015/05/23 11:22:33.123456789 [tid] label: The contents of the what field.
|
168
169
|
static int
|
169
|
-
classic_write(
|
170
|
+
classic_write(agooLogEntry e, FILE *file) {
|
170
171
|
time_t t = (time_t)(e->when / 1000000000LL);
|
171
172
|
int hour = 0;
|
172
173
|
int min = 0;
|
@@ -175,9 +176,9 @@ classic_write(LogEntry e, FILE *file) {
|
|
175
176
|
char levelc = level_chars[e->cat->level];
|
176
177
|
int cnt = 0;
|
177
178
|
|
178
|
-
t +=
|
179
|
-
if (
|
180
|
-
t -=
|
179
|
+
t += agoo_log.zone;
|
180
|
+
if (agoo_log.day_start <= t && t < agoo_log.day_end) {
|
181
|
+
t -= agoo_log.day_start;
|
181
182
|
hour = (int)(t / 3600);
|
182
183
|
min = t % 3600 / 60;
|
183
184
|
sec = t % 60;
|
@@ -187,20 +188,20 @@ classic_write(LogEntry e, FILE *file) {
|
|
187
188
|
hour = tm->tm_hour;
|
188
189
|
min = tm->tm_min;
|
189
190
|
sec = tm->tm_sec;
|
190
|
-
sprintf(
|
191
|
-
|
192
|
-
|
191
|
+
sprintf(agoo_log.day_buf, "%04d/%02d/%02d ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
|
192
|
+
agoo_log.day_start = t - (hour * 3600 + min * 60 + sec);
|
193
|
+
agoo_log.day_end = agoo_log.day_start + 86400;
|
193
194
|
}
|
194
|
-
if (
|
195
|
+
if (agoo_log.colorize) {
|
195
196
|
if (NULL == e->tidp && '\0' == *e->tid) {
|
196
197
|
cnt = fprintf(file, "%s%c %s%02d:%02d:%02d.%09lld %s: %s%s\n",
|
197
|
-
e->cat->color->ansi, levelc,
|
198
|
+
e->cat->color->ansi, levelc, agoo_log.day_buf, hour, min, sec, frac,
|
198
199
|
e->cat->label,
|
199
200
|
(NULL == e->whatp ? e->what : e->whatp),
|
200
201
|
RESET_COLOR);
|
201
202
|
} else {
|
202
203
|
cnt = fprintf(file, "%s%c %s%02d:%02d:%02d.%09lld [%s] %s: %s%s\n",
|
203
|
-
e->cat->color->ansi, levelc,
|
204
|
+
e->cat->color->ansi, levelc, agoo_log.day_buf, hour, min, sec, frac,
|
204
205
|
(NULL == e->tidp ? e->tid : e->tidp),
|
205
206
|
e->cat->label,
|
206
207
|
(NULL == e->whatp ? e->what : e->whatp),
|
@@ -209,12 +210,12 @@ classic_write(LogEntry e, FILE *file) {
|
|
209
210
|
} else {
|
210
211
|
if (NULL == e->tidp && '\0' == *e->tid) {
|
211
212
|
cnt += fprintf(file, "%c %s%02d:%02d:%02d.%09lld %s: %s\n",
|
212
|
-
levelc,
|
213
|
+
levelc, agoo_log.day_buf, hour, min, sec, frac,
|
213
214
|
e->cat->label,
|
214
215
|
(NULL == e->whatp ? e->what : e->whatp));
|
215
216
|
} else {
|
216
217
|
cnt += fprintf(file, "%c %s%02d:%02d:%02d.%09lld [%s] %s: %s\n",
|
217
|
-
levelc,
|
218
|
+
levelc, agoo_log.day_buf, hour, min, sec, frac,
|
218
219
|
(NULL == e->tidp ? e->tid : e->tidp),
|
219
220
|
e->cat->label,
|
220
221
|
(NULL == e->whatp ? e->what : e->whatp));
|
@@ -231,17 +232,17 @@ remove_old_logs() {
|
|
231
232
|
long seq;
|
232
233
|
char *end;
|
233
234
|
char path[1500];
|
234
|
-
DIR *dir = opendir(
|
235
|
+
DIR *dir = opendir(agoo_log.dir);
|
235
236
|
char prefix[64];
|
236
237
|
int psize;
|
237
238
|
char name[64];
|
238
239
|
|
239
|
-
if (
|
240
|
-
psize = sprintf(prefix, "%s_%d.log.",
|
241
|
-
sprintf(name, "%s_%d.log",
|
240
|
+
if (agoo_log.with_pid) {
|
241
|
+
psize = sprintf(prefix, "%s_%d.log.", agoo_log.app, getpid());
|
242
|
+
sprintf(name, "%s_%d.log", agoo_log.app, getpid());
|
242
243
|
} else {
|
243
|
-
psize = sprintf(prefix, "%s.log.",
|
244
|
-
sprintf(name, "%s.log",
|
244
|
+
psize = sprintf(prefix, "%s.log.", agoo_log.app);
|
245
|
+
sprintf(name, "%s.log", agoo_log.app);
|
245
246
|
}
|
246
247
|
while (NULL != (de = readdir(dir))) {
|
247
248
|
if ('.' == *de->d_name || '\0' == *de->d_name) {
|
@@ -255,8 +256,8 @@ remove_old_logs() {
|
|
255
256
|
continue;
|
256
257
|
}
|
257
258
|
seq = strtol(de->d_name + psize, &end, 10);
|
258
|
-
if (
|
259
|
-
snprintf(path, sizeof(path), "%s/%s",
|
259
|
+
if (agoo_log.max_files < seq) {
|
260
|
+
snprintf(path, sizeof(path), "%s/%s", agoo_log.dir, de->d_name);
|
260
261
|
remove(path);
|
261
262
|
}
|
262
263
|
}
|
@@ -264,72 +265,72 @@ remove_old_logs() {
|
|
264
265
|
}
|
265
266
|
|
266
267
|
void
|
267
|
-
|
268
|
+
agoo_log_rotate() {
|
268
269
|
char from[1060];
|
269
270
|
char to[1060];
|
270
271
|
|
271
|
-
if (NULL !=
|
272
|
-
fclose(
|
273
|
-
|
272
|
+
if (NULL != agoo_log.file) {
|
273
|
+
fclose(agoo_log.file);
|
274
|
+
agoo_log.file = NULL;
|
274
275
|
}
|
275
|
-
if (
|
276
|
+
if (agoo_log.with_pid) {
|
276
277
|
char name[32];
|
277
278
|
|
278
|
-
sprintf(name, "%s_%d.log",
|
279
|
-
for (int seq =
|
280
|
-
snprintf(to, sizeof(to) - 1, "%s/%s_%d.log.%d",
|
281
|
-
snprintf(from, sizeof(from) - 1, "%s/%s_%d.log.%d",
|
279
|
+
sprintf(name, "%s_%d.log", agoo_log.app, getpid());
|
280
|
+
for (int seq = agoo_log.max_files; 0 < seq; seq--) {
|
281
|
+
snprintf(to, sizeof(to) - 1, "%s/%s_%d.log.%d", agoo_log.dir, agoo_log.app, getpid(), seq + 1);
|
282
|
+
snprintf(from, sizeof(from) - 1, "%s/%s_%d.log.%d", agoo_log.dir, agoo_log.app, getpid(), seq);
|
282
283
|
rename(from, to);
|
283
284
|
}
|
284
|
-
snprintf(to, sizeof(to) - 1, "%s/%s_%d.log.%d",
|
285
|
-
snprintf(from, sizeof(from) - 1, "%s/%s",
|
285
|
+
snprintf(to, sizeof(to) - 1, "%s/%s_%d.log.%d", agoo_log.dir, agoo_log.app, getpid(), 1);
|
286
|
+
snprintf(from, sizeof(from) - 1, "%s/%s", agoo_log.dir, name);
|
286
287
|
} else {
|
287
|
-
for (int seq =
|
288
|
-
snprintf(to, sizeof(to) - 1, "%s/%s.log.%d",
|
289
|
-
snprintf(from, sizeof(from) - 1, "%s/%s.log.%d",
|
288
|
+
for (int seq = agoo_log.max_files; 0 < seq; seq--) {
|
289
|
+
snprintf(to, sizeof(to) - 1, "%s/%s.log.%d", agoo_log.dir, agoo_log.app, seq + 1);
|
290
|
+
snprintf(from, sizeof(from) - 1, "%s/%s.log.%d", agoo_log.dir, agoo_log.app, seq);
|
290
291
|
rename(from, to);
|
291
292
|
}
|
292
|
-
snprintf(to, sizeof(to) - 1, "%s/%s.log.%d",
|
293
|
-
snprintf(from, sizeof(from) - 1, "%s/%s.log",
|
293
|
+
snprintf(to, sizeof(to) - 1, "%s/%s.log.%d", agoo_log.dir, agoo_log.app, 1);
|
294
|
+
snprintf(from, sizeof(from) - 1, "%s/%s.log", agoo_log.dir, agoo_log.app);
|
294
295
|
}
|
295
296
|
rename(from, to);
|
296
297
|
|
297
|
-
|
298
|
-
|
298
|
+
agoo_log.file = fopen(from, "w");
|
299
|
+
agoo_log.size = 0;
|
299
300
|
|
300
301
|
remove_old_logs();
|
301
302
|
}
|
302
303
|
|
303
304
|
static void*
|
304
305
|
loop(void *ctx) {
|
305
|
-
|
306
|
+
agooLogEntry e;
|
306
307
|
|
307
|
-
while (!
|
308
|
-
if (NULL != (e =
|
309
|
-
if (
|
310
|
-
if (
|
308
|
+
while (!agoo_log.done || !agoo_log_queue_empty()) {
|
309
|
+
if (NULL != (e = agoo_log_queue_pop(0.5))) {
|
310
|
+
if (agoo_log.console) {
|
311
|
+
if (agoo_log.classic) {
|
311
312
|
classic_write(e, stdout);
|
312
313
|
} else {
|
313
314
|
jwrite(e, stdout);
|
314
315
|
}
|
315
316
|
}
|
316
|
-
if (NULL !=
|
317
|
-
if (
|
318
|
-
|
317
|
+
if (NULL != agoo_log.file) {
|
318
|
+
if (agoo_log.classic) {
|
319
|
+
agoo_log.size += classic_write(e, agoo_log.file);
|
319
320
|
} else {
|
320
|
-
|
321
|
+
agoo_log.size += jwrite(e, agoo_log.file);
|
321
322
|
}
|
322
|
-
if (
|
323
|
-
|
323
|
+
if (agoo_log.max_size <= agoo_log.size) {
|
324
|
+
agoo_log_rotate();
|
324
325
|
}
|
325
326
|
}
|
326
327
|
if (NULL != e->whatp) {
|
327
328
|
free(e->whatp);
|
328
|
-
DEBUG_FREE(
|
329
|
+
DEBUG_FREE(mem_agoo_log_what, e->whatp)
|
329
330
|
}
|
330
331
|
if (NULL != e->tidp) {
|
331
332
|
free(e->tidp);
|
332
|
-
DEBUG_FREE(
|
333
|
+
DEBUG_FREE(mem_agoo_log_tid, e->tidp)
|
333
334
|
}
|
334
335
|
e->ready = false;
|
335
336
|
}
|
@@ -338,76 +339,76 @@ loop(void *ctx) {
|
|
338
339
|
}
|
339
340
|
|
340
341
|
bool
|
341
|
-
|
342
|
+
agoo_log_flush(double timeout) {
|
342
343
|
timeout += dtime();
|
343
344
|
|
344
|
-
while (!
|
345
|
+
while (!agoo_log.done && !agoo_log_queue_empty()) {
|
345
346
|
if (timeout < dtime()) {
|
346
347
|
return false;
|
347
348
|
}
|
348
349
|
dsleep(0.001);
|
349
350
|
}
|
350
|
-
if (NULL !=
|
351
|
-
fflush(
|
351
|
+
if (NULL != agoo_log.file) {
|
352
|
+
fflush(agoo_log.file);
|
352
353
|
}
|
353
354
|
return true;
|
354
355
|
}
|
355
356
|
|
356
357
|
void
|
357
|
-
|
358
|
+
agoo_log_open_file() {
|
358
359
|
char path[1500];
|
359
360
|
|
360
|
-
if (
|
361
|
-
snprintf(path, sizeof(path), "%s/%s_%d.log",
|
361
|
+
if (agoo_log.with_pid) {
|
362
|
+
snprintf(path, sizeof(path), "%s/%s_%d.log", agoo_log.dir, agoo_log.app, getpid());
|
362
363
|
} else {
|
363
|
-
snprintf(path, sizeof(path), "%s/%s.log",
|
364
|
+
snprintf(path, sizeof(path), "%s/%s.log", agoo_log.dir, agoo_log.app);
|
364
365
|
}
|
365
|
-
|
366
|
-
if (NULL ==
|
367
|
-
struct
|
366
|
+
agoo_log.file = fopen(path, "a");
|
367
|
+
if (NULL == agoo_log.file) {
|
368
|
+
struct _agooErr err;
|
368
369
|
|
369
|
-
|
370
|
-
|
370
|
+
agoo_err_no(&err, "Failed to create '%s'.", path);
|
371
|
+
agoo_log.on_error(&err);
|
371
372
|
}
|
372
|
-
|
373
|
-
if (
|
374
|
-
|
373
|
+
agoo_log.size = ftell(agoo_log.file);
|
374
|
+
if (agoo_log.max_size <= agoo_log.size) {
|
375
|
+
agoo_log_rotate();
|
375
376
|
}
|
376
377
|
// TBD open rsock and wsock
|
377
378
|
}
|
378
379
|
|
379
380
|
void
|
380
|
-
|
381
|
-
|
381
|
+
agoo_log_close() {
|
382
|
+
agoo_log.done = true;
|
382
383
|
// TBD wake up loop like push does
|
383
|
-
|
384
|
-
if (0 !=
|
385
|
-
pthread_join(
|
386
|
-
|
384
|
+
agoo_log_cat_on(NULL, false);
|
385
|
+
if (0 != agoo_log.thread) {
|
386
|
+
pthread_join(agoo_log.thread, NULL);
|
387
|
+
agoo_log.thread = 0;
|
387
388
|
}
|
388
|
-
if (NULL !=
|
389
|
-
fclose(
|
390
|
-
|
389
|
+
if (NULL != agoo_log.file) {
|
390
|
+
fclose(agoo_log.file);
|
391
|
+
agoo_log.file = NULL;
|
391
392
|
}
|
392
|
-
if (NULL !=
|
393
|
-
DEBUG_FREE(
|
394
|
-
free(
|
395
|
-
|
396
|
-
|
393
|
+
if (NULL != agoo_log.q) {
|
394
|
+
DEBUG_FREE(mem_agoo_log_entry, agoo_log.q);
|
395
|
+
free(agoo_log.q);
|
396
|
+
agoo_log.q = NULL;
|
397
|
+
agoo_log.end = NULL;
|
397
398
|
}
|
398
|
-
if (0 <
|
399
|
-
close(
|
400
|
-
|
399
|
+
if (0 < agoo_log.wsock) {
|
400
|
+
close(agoo_log.wsock);
|
401
|
+
agoo_log.wsock = 0;
|
401
402
|
}
|
402
|
-
if (0 <
|
403
|
-
close(
|
404
|
-
|
403
|
+
if (0 < agoo_log.rsock) {
|
404
|
+
close(agoo_log.rsock);
|
405
|
+
agoo_log.rsock = 0;
|
405
406
|
}
|
406
407
|
}
|
407
408
|
|
408
409
|
void
|
409
|
-
|
410
|
-
|
410
|
+
agoo_log_cat_reg(agooLogCat cat, const char *label, agooLogLevel level, const char *color, bool on) {
|
411
|
+
agooLogCat xcat = agoo_log_cat_find(label);
|
411
412
|
|
412
413
|
if (NULL != xcat) {
|
413
414
|
cat = xcat;
|
@@ -418,16 +419,16 @@ log_cat_reg(LogCat cat, const char *label, LogLevel level, const char *color, bo
|
|
418
419
|
cat->color = find_color(color);
|
419
420
|
cat->on = on;
|
420
421
|
if (NULL == xcat) {
|
421
|
-
cat->next =
|
422
|
-
|
422
|
+
cat->next = agoo_log.cats;
|
423
|
+
agoo_log.cats = cat;
|
423
424
|
}
|
424
425
|
}
|
425
426
|
|
426
427
|
void
|
427
|
-
|
428
|
-
|
428
|
+
agoo_log_cat_on(const char *label, bool on) {
|
429
|
+
agooLogCat cat;
|
429
430
|
|
430
|
-
for (cat =
|
431
|
+
for (cat = agoo_log.cats; NULL != cat; cat = cat->next) {
|
431
432
|
if (NULL == label || 0 == strcasecmp(label, cat->label)) {
|
432
433
|
cat->on = on;
|
433
434
|
break;
|
@@ -435,11 +436,11 @@ log_cat_on(const char *label, bool on) {
|
|
435
436
|
}
|
436
437
|
}
|
437
438
|
|
438
|
-
|
439
|
-
|
440
|
-
|
439
|
+
agooLogCat
|
440
|
+
agoo_log_cat_find(const char *label) {
|
441
|
+
agooLogCat cat;
|
441
442
|
|
442
|
-
for (cat =
|
443
|
+
for (cat = agoo_log.cats; NULL != cat; cat = cat->next) {
|
443
444
|
if (0 == strcasecmp(label, cat->label)) {
|
444
445
|
return cat;
|
445
446
|
}
|
@@ -468,7 +469,7 @@ now_nano() {
|
|
468
469
|
#endif
|
469
470
|
|
470
471
|
static void
|
471
|
-
set_entry(
|
472
|
+
set_entry(agooLogEntry e, agooLogCat cat, const char *tid, const char *fmt, va_list ap) {
|
472
473
|
int cnt;
|
473
474
|
va_list ap2;
|
474
475
|
|
@@ -502,135 +503,142 @@ set_entry(LogEntry e, LogCat cat, const char *tid, const char *fmt, va_list ap)
|
|
502
503
|
}
|
503
504
|
|
504
505
|
void
|
505
|
-
|
506
|
-
if (cat->on && !
|
507
|
-
|
508
|
-
|
506
|
+
agoo_log_catv(agooLogCat cat, const char *tid, const char *fmt, va_list ap) {
|
507
|
+
if (cat->on && !agoo_log.done) {
|
508
|
+
agooLogEntry e;
|
509
|
+
agooLogEntry tail;
|
509
510
|
|
510
|
-
while (atomic_flag_test_and_set(&
|
511
|
+
while (atomic_flag_test_and_set(&agoo_log.push_lock)) {
|
511
512
|
dsleep(RETRY_SECS);
|
512
513
|
}
|
513
|
-
if (0 ==
|
514
|
-
struct
|
514
|
+
if (0 == agoo_log.thread) {
|
515
|
+
struct _agooLogEntry entry;
|
515
516
|
|
516
517
|
set_entry(&entry, cat, tid, fmt, ap);
|
517
|
-
if (
|
518
|
+
if (agoo_log.classic) {
|
518
519
|
classic_write(&entry, stdout);
|
519
520
|
} else {
|
520
521
|
jwrite(&entry, stdout);
|
521
522
|
}
|
522
|
-
atomic_flag_clear(&
|
523
|
+
atomic_flag_clear(&agoo_log.push_lock);
|
524
|
+
|
525
|
+
return;
|
523
526
|
}
|
524
527
|
// Wait for head to move on.
|
525
|
-
while (atomic_load(&
|
528
|
+
while (atomic_load(&agoo_log.head) == atomic_load(&agoo_log.tail)) {
|
526
529
|
dsleep(RETRY_SECS);
|
527
530
|
}
|
528
|
-
e =
|
531
|
+
e = atomic_load(&agoo_log.tail);
|
529
532
|
set_entry(e, cat, tid, fmt, ap);
|
530
|
-
tail =
|
531
|
-
if (
|
532
|
-
tail =
|
533
|
+
tail = e + 1;
|
534
|
+
if (agoo_log.end <= tail) {
|
535
|
+
tail = agoo_log.q;
|
533
536
|
}
|
534
|
-
atomic_store(&
|
535
|
-
atomic_flag_clear(&
|
537
|
+
atomic_store(&agoo_log.tail, tail);
|
538
|
+
atomic_flag_clear(&agoo_log.push_lock);
|
536
539
|
|
537
|
-
if (0 !=
|
538
|
-
if (write(
|
539
|
-
atomic_store(&
|
540
|
+
if (0 != agoo_log.wsock && WAITING == (int)(long)atomic_load(&agoo_log.wait_state)) {
|
541
|
+
if (write(agoo_log.wsock, ".", 1)) {}
|
542
|
+
atomic_store(&agoo_log.wait_state, NOTIFIED);
|
540
543
|
}
|
541
544
|
}
|
542
545
|
}
|
543
546
|
|
544
547
|
void
|
545
|
-
|
548
|
+
agoo_log_cat(agooLogCat cat, const char *fmt, ...) {
|
546
549
|
va_list ap;
|
547
550
|
|
548
551
|
va_start(ap, fmt);
|
549
|
-
|
552
|
+
agoo_log_catv(cat, NULL, fmt, ap);
|
550
553
|
va_end(ap);
|
551
554
|
}
|
552
555
|
|
553
556
|
void
|
554
|
-
|
557
|
+
agoo_log_tid_cat(agooLogCat cat, const char *tid, const char *fmt, ...) {
|
555
558
|
va_list ap;
|
556
559
|
|
557
560
|
va_start(ap, fmt);
|
558
|
-
|
561
|
+
agoo_log_catv(cat, tid, fmt, ap);
|
559
562
|
va_end(ap);
|
560
563
|
}
|
561
564
|
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
+
int
|
566
|
+
agoo_log_start(agooErr err, bool with_pid) {
|
567
|
+
int stat;
|
568
|
+
|
569
|
+
if (0 != agoo_log.thread) {
|
565
570
|
// Already started.
|
566
|
-
return;
|
571
|
+
return AGOO_ERR_OK;
|
567
572
|
}
|
568
|
-
if (NULL !=
|
569
|
-
fclose(
|
570
|
-
|
573
|
+
if (NULL != agoo_log.file) {
|
574
|
+
fclose(agoo_log.file);
|
575
|
+
agoo_log.file = NULL;
|
571
576
|
// TBD close rsock and wsock
|
572
577
|
}
|
573
|
-
|
574
|
-
if ('\0' != *
|
575
|
-
if (0 != mkdir(
|
576
|
-
struct
|
578
|
+
agoo_log.with_pid = with_pid;
|
579
|
+
if ('\0' != *agoo_log.dir) {
|
580
|
+
if (0 != mkdir(agoo_log.dir, 0770) && EEXIST != errno) {
|
581
|
+
struct _agooErr err;
|
577
582
|
|
578
|
-
|
579
|
-
|
583
|
+
agoo_err_no(&err, "Failed to create '%s'", agoo_log.dir);
|
584
|
+
agoo_log.on_error(&err);
|
580
585
|
}
|
581
|
-
|
586
|
+
agoo_log_open_file();
|
587
|
+
}
|
588
|
+
if (0 != (stat = pthread_create(&agoo_log.thread, NULL, loop, NULL))) {
|
589
|
+
return agoo_err_set(err, stat, "Failed to create log thread. %s", strerror(stat));
|
582
590
|
}
|
583
|
-
|
591
|
+
return AGOO_ERR_OK;
|
584
592
|
}
|
585
593
|
|
586
594
|
void
|
587
|
-
|
595
|
+
agoo_log_init(const char *app) {
|
588
596
|
time_t t = time(NULL);
|
589
597
|
struct tm *tm = localtime(&t);
|
590
598
|
int qsize = 1024;
|
591
599
|
|
592
|
-
strncpy(
|
593
|
-
|
594
|
-
|
595
|
-
*
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
*
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
DEBUG_ALLOC(mem_log_entry,
|
613
|
-
|
614
|
-
memset(
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
600
|
+
strncpy(agoo_log.app, app, sizeof(agoo_log.app));
|
601
|
+
agoo_log.app[sizeof(agoo_log.app) - 1] = '\0';
|
602
|
+
agoo_log.cats = NULL;
|
603
|
+
*agoo_log.dir = '\0';
|
604
|
+
agoo_log.file = NULL;
|
605
|
+
agoo_log.max_files = 3;
|
606
|
+
agoo_log.max_size = 100000000; // 100M
|
607
|
+
agoo_log.size = 0;
|
608
|
+
agoo_log.done = false;
|
609
|
+
agoo_log.console = true;
|
610
|
+
agoo_log.classic = true;
|
611
|
+
agoo_log.colorize = true;
|
612
|
+
agoo_log.with_pid = false;
|
613
|
+
agoo_log.zone = (int)(timegm(tm) - t);
|
614
|
+
agoo_log.day_start = 0;
|
615
|
+
agoo_log.day_end = 0;
|
616
|
+
*agoo_log.day_buf = '\0';
|
617
|
+
agoo_log.thread = 0;
|
618
|
+
|
619
|
+
agoo_log.q = (agooLogEntry)malloc(sizeof(struct _agooLogEntry) * qsize);
|
620
|
+
DEBUG_ALLOC(mem_log_entry, agoo_log.q)
|
621
|
+
agoo_log.end = agoo_log.q + qsize;
|
622
|
+
memset(agoo_log.q, 0, sizeof(struct _agooLogEntry) * qsize);
|
623
|
+
atomic_init(&agoo_log.head, agoo_log.q);
|
624
|
+
atomic_init(&agoo_log.tail, agoo_log.q + 1);
|
625
|
+
|
626
|
+
agoo_atomic_flag_init(&agoo_log.push_lock);
|
627
|
+
atomic_init(&agoo_log.wait_state, NOT_WAITING);
|
620
628
|
// Create when/if needed.
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
//
|
629
|
+
agoo_log.rsock = 0;
|
630
|
+
agoo_log.wsock = 0;
|
631
|
+
|
632
|
+
agoo_log_cat_reg(&agoo_fatal_cat, "FATAL", AGOO_FATAL, AGOO_RED, true);
|
633
|
+
agoo_log_cat_reg(&agoo_error_cat, "ERROR", AGOO_ERROR, AGOO_RED, true);
|
634
|
+
agoo_log_cat_reg(&agoo_warn_cat, "WARN", AGOO_WARN, AGOO_YELLOW, true);
|
635
|
+
agoo_log_cat_reg(&agoo_info_cat, "INFO", AGOO_INFO, AGOO_GREEN, true);
|
636
|
+
agoo_log_cat_reg(&agoo_debug_cat, "DEBUG", AGOO_DEBUG, AGOO_GRAY, false);
|
637
|
+
agoo_log_cat_reg(&agoo_con_cat, "connect", AGOO_INFO, AGOO_GREEN, false);
|
638
|
+
agoo_log_cat_reg(&agoo_req_cat, "request", AGOO_INFO, AGOO_CYAN, false);
|
639
|
+
agoo_log_cat_reg(&agoo_resp_cat, "response", AGOO_INFO, AGOO_DARK_CYAN, false);
|
640
|
+
agoo_log_cat_reg(&agoo_eval_cat, "eval", AGOO_INFO, AGOO_BLUE, false);
|
641
|
+
agoo_log_cat_reg(&agoo_push_cat, "push", AGOO_INFO, AGOO_DARK_CYAN, false);
|
642
|
+
|
643
|
+
//agoo_log_start(false);
|
636
644
|
}
|