agoo 2.2.2 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of agoo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/ext/agoo/agoo.c +2 -2
- data/ext/agoo/con.c +65 -62
- data/ext/agoo/debug.c +3 -2
- data/ext/agoo/extconf.rb +4 -2
- data/ext/agoo/hook.c +15 -74
- data/ext/agoo/hook.h +20 -12
- data/ext/agoo/log.c +30 -466
- data/ext/agoo/log.h +6 -5
- data/ext/agoo/method.h +25 -0
- data/ext/agoo/request.c +27 -23
- data/ext/agoo/request.h +1 -0
- data/ext/agoo/response.c +0 -1
- data/ext/agoo/rhook.c +82 -0
- data/ext/agoo/rhook.h +13 -0
- data/ext/agoo/rlog.c +469 -0
- data/ext/agoo/rlog.h +11 -0
- data/ext/agoo/seg.h +11 -0
- data/ext/agoo/server.c +22 -8
- data/ext/agoo/server.h +1 -1
- data/ext/agoo/types.h +0 -19
- data/ext/agoo/upgraded.c +13 -1
- data/ext/agoo/upgraded.h +2 -1
- data/ext/agoo/websocket.c +3 -3
- data/lib/agoo/version.rb +1 -1
- metadata +9 -3
data/ext/agoo/hook.h
CHANGED
@@ -5,30 +5,38 @@
|
|
5
5
|
|
6
6
|
#include <stdbool.h>
|
7
7
|
|
8
|
-
#include
|
9
|
-
|
10
|
-
#include "types.h"
|
8
|
+
#include "method.h"
|
9
|
+
#include "seg.h"
|
11
10
|
|
12
11
|
typedef enum {
|
13
|
-
NO_HOOK
|
14
|
-
RACK_HOOK
|
15
|
-
BASE_HOOK
|
16
|
-
WAB_HOOK
|
17
|
-
PUSH_HOOK
|
12
|
+
NO_HOOK = '\0',
|
13
|
+
RACK_HOOK = 'R',
|
14
|
+
BASE_HOOK = 'B',
|
15
|
+
WAB_HOOK = 'W',
|
16
|
+
PUSH_HOOK = 'P',
|
17
|
+
STDIO_HOOK = 'S', // for OpO
|
18
|
+
FAST_HOOK = 'F', // for OpO
|
19
|
+
GET_HOOK = 'G', // for OpO
|
20
|
+
TNEW_HOOK = 'c', // for OpO
|
21
|
+
TGET_HOOK = 'r', // for OpO
|
22
|
+
TUP_HOOK = 'u', // for OpO
|
23
|
+
TDEL_HOOK = 'd', // for OpO
|
24
|
+
TQL_HOOK = 'T', // for OpO
|
25
|
+
GRAPHQL_HOOK = 'Q', // for OpO
|
18
26
|
} HookType;
|
19
27
|
|
20
28
|
typedef struct _Hook {
|
21
29
|
struct _Hook *next;
|
22
30
|
Method method;
|
23
|
-
VALUE handler;
|
24
31
|
char *pattern;
|
25
32
|
HookType type;
|
33
|
+
void* handler;
|
26
34
|
} *Hook;
|
27
35
|
|
28
|
-
extern Hook hook_create(Method method, const char *pattern,
|
36
|
+
extern Hook hook_create(Method method, const char *pattern, void *handler, HookType type);
|
29
37
|
extern void hook_destroy(Hook hook);
|
30
38
|
|
31
|
-
extern bool hook_match(Hook hook, Method method, const
|
32
|
-
extern Hook hook_find(Hook hook, Method method, const
|
39
|
+
extern bool hook_match(Hook hook, Method method, const Seg seg);
|
40
|
+
extern Hook hook_find(Hook hook, Method method, const Seg seg);
|
33
41
|
|
34
42
|
#endif // __AGOO_HOOK_H__
|
data/ext/agoo/log.c
CHANGED
@@ -54,8 +54,6 @@ static struct _Color colors[] = {
|
|
54
54
|
|
55
55
|
static const char level_chars[] = { 'F', 'E', 'W', 'I', 'D', '?' };
|
56
56
|
|
57
|
-
static VALUE log_mod = Qundef;
|
58
|
-
|
59
57
|
struct _Log the_log = {NULL};
|
60
58
|
struct _LogCat fatal_cat;
|
61
59
|
struct _LogCat error_cat;
|
@@ -68,7 +66,7 @@ struct _LogCat resp_cat;
|
|
68
66
|
struct _LogCat eval_cat;
|
69
67
|
struct _LogCat push_cat;
|
70
68
|
|
71
|
-
|
69
|
+
Color
|
72
70
|
find_color(const char *name) {
|
73
71
|
if (NULL != name) {
|
74
72
|
for (Color c = colors; NULL != c->name; c++) {
|
@@ -212,7 +210,7 @@ remove_old_logs() {
|
|
212
210
|
struct dirent *de;
|
213
211
|
long seq;
|
214
212
|
char *end;
|
215
|
-
char path[
|
213
|
+
char path[1500];
|
216
214
|
DIR *dir = opendir(the_log.dir);
|
217
215
|
char prefix[32];
|
218
216
|
int psize;
|
@@ -248,8 +246,8 @@ remove_old_logs() {
|
|
248
246
|
|
249
247
|
void
|
250
248
|
log_rotate() {
|
251
|
-
char from[
|
252
|
-
char to[
|
249
|
+
char from[1060];
|
250
|
+
char to[1060];
|
253
251
|
|
254
252
|
if (NULL != the_log.file) {
|
255
253
|
fclose(the_log.file);
|
@@ -260,20 +258,20 @@ log_rotate() {
|
|
260
258
|
|
261
259
|
sprintf(name, log_pid_name, getpid());
|
262
260
|
for (int seq = the_log.max_files; 0 < seq; seq--) {
|
263
|
-
snprintf(to, sizeof(to), log_pid_format, the_log.dir, getpid(), seq + 1);
|
264
|
-
snprintf(from, sizeof(from), log_pid_format, the_log.dir, getpid(), seq);
|
261
|
+
snprintf(to, sizeof(to) - 1, log_pid_format, the_log.dir, getpid(), seq + 1);
|
262
|
+
snprintf(from, sizeof(from) - 1, log_pid_format, the_log.dir, getpid(), seq);
|
265
263
|
rename(from, to);
|
266
264
|
}
|
267
|
-
snprintf(to, sizeof(to), log_pid_format, the_log.dir, getpid(), 1);
|
268
|
-
snprintf(from, sizeof(from), "%s/%s", the_log.dir, name);
|
265
|
+
snprintf(to, sizeof(to) - 1, log_pid_format, the_log.dir, getpid(), 1);
|
266
|
+
snprintf(from, sizeof(from) - 1, "%s/%s", the_log.dir, name);
|
269
267
|
} else {
|
270
268
|
for (int seq = the_log.max_files; 0 < seq; seq--) {
|
271
|
-
snprintf(to, sizeof(to), log_format, the_log.dir, seq + 1);
|
272
|
-
snprintf(from, sizeof(from), log_format, the_log.dir, seq);
|
269
|
+
snprintf(to, sizeof(to) - 1, log_format, the_log.dir, seq + 1);
|
270
|
+
snprintf(from, sizeof(from) - 1, log_format, the_log.dir, seq);
|
273
271
|
rename(from, to);
|
274
272
|
}
|
275
|
-
snprintf(to, sizeof(to), log_format, the_log.dir, 1);
|
276
|
-
snprintf(from, sizeof(from), "%s/%s", the_log.dir, log_name);
|
273
|
+
snprintf(to, sizeof(to) - 1, log_format, the_log.dir, 1);
|
274
|
+
snprintf(from, sizeof(from) - 1, "%s/%s", the_log.dir, log_name);
|
277
275
|
}
|
278
276
|
rename(from, to);
|
279
277
|
|
@@ -332,9 +330,9 @@ log_flush(double timeout) {
|
|
332
330
|
return true;
|
333
331
|
}
|
334
332
|
|
335
|
-
|
333
|
+
void
|
336
334
|
open_log_file() {
|
337
|
-
char path[
|
335
|
+
char path[1500];
|
338
336
|
|
339
337
|
if (the_log.with_pid) {
|
340
338
|
snprintf(path, sizeof(path), "%s/%s_%d", the_log.dir, log_name, getpid());
|
@@ -343,13 +341,16 @@ open_log_file() {
|
|
343
341
|
}
|
344
342
|
the_log.file = fopen(path, "a");
|
345
343
|
if (NULL == the_log.file) {
|
346
|
-
|
344
|
+
struct _Err err;
|
345
|
+
|
346
|
+
err_no(&err, "Failed to create '%s'.", path);
|
347
|
+
the_log.on_error(&err);
|
347
348
|
}
|
348
349
|
the_log.size = ftell(the_log.file);
|
349
350
|
if (the_log.max_size <= the_log.size) {
|
350
351
|
log_rotate();
|
351
352
|
}
|
352
|
-
// TBD open
|
353
|
+
// TBD open rsock and wsock
|
353
354
|
}
|
354
355
|
|
355
356
|
void
|
@@ -442,7 +443,6 @@ log_catv(LogCat cat, const char *fmt, va_list ap) {
|
|
442
443
|
struct timezone tz;
|
443
444
|
|
444
445
|
gettimeofday(&tv, &tz);
|
445
|
-
|
446
446
|
e->when = (int64_t)tv.tv_sec * 1000000000LL + (int64_t)tv.tv_usec * 1000.0;
|
447
447
|
#endif
|
448
448
|
}
|
@@ -480,451 +480,32 @@ log_cat(LogCat cat, const char *fmt, ...) {
|
|
480
480
|
va_end(ap);
|
481
481
|
}
|
482
482
|
|
483
|
-
|
484
|
-
|
485
|
-
* call-seq: configure(options)
|
486
|
-
*
|
487
|
-
* Configures the logger
|
488
|
-
*
|
489
|
-
* - *options* [_Hash_] server options
|
490
|
-
*
|
491
|
-
* - *:dir* [_String_] directory to place log files in. If nil or empty then no log files are written.
|
492
|
-
*
|
493
|
-
* - *:console* [_true_|_false_] if true log entry are display on the console.
|
494
|
-
*
|
495
|
-
* - *:classic* [_true_|_false_] if true log entry follow a classic format. If false log entries are JSON.
|
496
|
-
*
|
497
|
-
* - *:colorize* [_true_|_false_] if true log entries are colorized.
|
498
|
-
*
|
499
|
-
* - *:states* [_Hash_] a map of logging categories and whether they should be on or off. Categories are:
|
500
|
-
* - *:ERROR* errors
|
501
|
-
* - *:WARN* warnings
|
502
|
-
* - *:INFO* infomational
|
503
|
-
* - *:DEBUG* debugging
|
504
|
-
* - *:connect* openning and closing of connections
|
505
|
-
* - *:request* requests
|
506
|
-
* - *:response* responses
|
507
|
-
* - *:eval* handler evaluationss
|
508
|
-
* - *:push* writes to WebSocket or SSE connection
|
509
|
-
*/
|
510
|
-
static VALUE
|
511
|
-
rlog_configure(VALUE self, VALUE options) {
|
512
|
-
if (Qnil != options) {
|
513
|
-
VALUE v;
|
514
|
-
|
515
|
-
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("dir"))))) {
|
516
|
-
rb_check_type(v, T_STRING);
|
517
|
-
strncpy(the_log.dir, StringValuePtr(v), sizeof(the_log.dir));
|
518
|
-
the_log.dir[sizeof(the_log.dir) - 1] = '\0';
|
519
|
-
}
|
520
|
-
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("max_files"))))) {
|
521
|
-
int max = FIX2INT(v);
|
522
|
-
|
523
|
-
if (1 <= max || max < 100) {
|
524
|
-
the_log.max_files = max;
|
525
|
-
} else {
|
526
|
-
rb_raise(rb_eArgError, "max_files must be between 1 and 100.");
|
527
|
-
}
|
528
|
-
}
|
529
|
-
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("max_size"))))) {
|
530
|
-
int max = FIX2INT(v);
|
531
|
-
|
532
|
-
if (1 <= max) {
|
533
|
-
the_log.max_size = max;
|
534
|
-
} else {
|
535
|
-
rb_raise(rb_eArgError, "max_size must be 1 or more.");
|
536
|
-
}
|
537
|
-
}
|
538
|
-
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("console"))))) {
|
539
|
-
the_log.console = (Qtrue == v);
|
540
|
-
}
|
541
|
-
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("classic"))))) {
|
542
|
-
the_log.classic = (Qtrue == v);
|
543
|
-
}
|
544
|
-
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("colorize"))))) {
|
545
|
-
the_log.colorize = (Qtrue == v);
|
546
|
-
}
|
547
|
-
if (Qnil != (v = rb_hash_lookup(options, ID2SYM(rb_intern("states"))))) {
|
548
|
-
if (T_HASH == rb_type(v)) {
|
549
|
-
LogCat cat = the_log.cats;
|
550
|
-
VALUE cv;
|
551
|
-
|
552
|
-
for (; NULL != cat; cat = cat->next) {
|
553
|
-
if (Qnil != (cv = rb_hash_lookup(v, ID2SYM(rb_intern(cat->label))))) {
|
554
|
-
if (Qtrue == cv) {
|
555
|
-
cat->on = true;
|
556
|
-
} else if (Qfalse == cv) {
|
557
|
-
cat->on = false;
|
558
|
-
}
|
559
|
-
}
|
560
|
-
}
|
561
|
-
} else {
|
562
|
-
rb_raise(rb_eArgError, "states must be a Hash.");
|
563
|
-
}
|
564
|
-
}
|
565
|
-
}
|
483
|
+
void
|
484
|
+
log_start(bool with_pid) {
|
566
485
|
if (NULL != the_log.file) {
|
567
486
|
fclose(the_log.file);
|
568
487
|
the_log.file = NULL;
|
488
|
+
// TBD close rsock and wsock
|
569
489
|
}
|
570
|
-
|
490
|
+
the_log.with_pid = with_pid;
|
491
|
+
if (with_pid && '\0' != *the_log.dir) {
|
571
492
|
if (0 != mkdir(the_log.dir, 0770) && EEXIST != errno) {
|
572
|
-
|
493
|
+
struct _Err err;
|
494
|
+
|
495
|
+
err_no(&err, "Failed to create '%s'", the_log.dir);
|
496
|
+
the_log.on_error(&err);
|
573
497
|
}
|
574
498
|
open_log_file();
|
575
499
|
}
|
576
|
-
|
577
|
-
}
|
578
|
-
|
579
|
-
/* Document-method: shutdown
|
580
|
-
*
|
581
|
-
* call-seq: shutdown()
|
582
|
-
*
|
583
|
-
* Shutdown the logger. Writes are flushed before shutting down.
|
584
|
-
*/
|
585
|
-
static VALUE
|
586
|
-
rlog_shutdown(VALUE self) {
|
587
|
-
log_close();
|
588
|
-
return Qnil;
|
589
|
-
}
|
590
|
-
|
591
|
-
/* Document-method: error?
|
592
|
-
*
|
593
|
-
* call-seq: error?()
|
594
|
-
*
|
595
|
-
* Returns true is errors are being logged.
|
596
|
-
*/
|
597
|
-
static VALUE
|
598
|
-
rlog_errorp(VALUE self) {
|
599
|
-
return error_cat.on ? Qtrue : Qfalse;
|
600
|
-
}
|
601
|
-
|
602
|
-
/* Document-method: warn?
|
603
|
-
*
|
604
|
-
* call-seq: warn?()
|
605
|
-
*
|
606
|
-
* Returns true is warnings are being logged.
|
607
|
-
*/
|
608
|
-
static VALUE
|
609
|
-
rlog_warnp(VALUE self) {
|
610
|
-
return warn_cat.on ? Qtrue : Qfalse;
|
611
|
-
}
|
612
|
-
|
613
|
-
/* Document-method: info?
|
614
|
-
*
|
615
|
-
* call-seq: info?()
|
616
|
-
*
|
617
|
-
* Returns true is info entries are being logged.
|
618
|
-
*/
|
619
|
-
static VALUE
|
620
|
-
rlog_infop(VALUE self) {
|
621
|
-
return info_cat.on ? Qtrue : Qfalse;
|
622
|
-
}
|
623
|
-
|
624
|
-
/* Document-method: debug?
|
625
|
-
*
|
626
|
-
* call-seq: debug?()
|
627
|
-
*
|
628
|
-
* Returns true is debug entries are being logged.
|
629
|
-
*/
|
630
|
-
static VALUE
|
631
|
-
rlog_debugp(VALUE self) {
|
632
|
-
return debug_cat.on ? Qtrue : Qfalse;
|
633
|
-
}
|
634
|
-
|
635
|
-
/* Document-method: error
|
636
|
-
*
|
637
|
-
* call-seq: error(msg)
|
638
|
-
*
|
639
|
-
* Log an error message.
|
640
|
-
*/
|
641
|
-
static VALUE
|
642
|
-
rlog_error(VALUE self, VALUE msg) {
|
643
|
-
log_cat(&error_cat, "%s", StringValuePtr(msg));
|
644
|
-
return Qnil;
|
645
|
-
}
|
646
|
-
|
647
|
-
/* Document-method: warn
|
648
|
-
*
|
649
|
-
* call-seq: warn(msg)
|
650
|
-
*
|
651
|
-
* Log a warn message.
|
652
|
-
*/
|
653
|
-
static VALUE
|
654
|
-
rlog_warn(VALUE self, VALUE msg) {
|
655
|
-
log_cat(&warn_cat, "%s", StringValuePtr(msg));
|
656
|
-
return Qnil;
|
657
|
-
}
|
658
|
-
|
659
|
-
/* Document-method: info
|
660
|
-
*
|
661
|
-
* call-seq: info(msg)
|
662
|
-
*
|
663
|
-
* Log an info message.
|
664
|
-
*/
|
665
|
-
static VALUE
|
666
|
-
rlog_info(VALUE self, VALUE msg) {
|
667
|
-
log_cat(&info_cat, "%s", StringValuePtr(msg));
|
668
|
-
return Qnil;
|
669
|
-
}
|
670
|
-
|
671
|
-
/* Document-method: debug
|
672
|
-
*
|
673
|
-
* call-seq: debug(msg)
|
674
|
-
*
|
675
|
-
* Log a debug message.
|
676
|
-
*/
|
677
|
-
static VALUE
|
678
|
-
rlog_debug(VALUE self, VALUE msg) {
|
679
|
-
log_cat(&debug_cat, "%s", StringValuePtr(msg));
|
680
|
-
return Qnil;
|
681
|
-
}
|
682
|
-
|
683
|
-
/* Document-method: color
|
684
|
-
*
|
685
|
-
* call-seq: color(label)
|
686
|
-
*
|
687
|
-
* Returns the current color name as a Symbol for the specified label.
|
688
|
-
*/
|
689
|
-
static VALUE
|
690
|
-
rlog_color_get(VALUE self, VALUE label) {
|
691
|
-
LogCat cat = log_cat_find(StringValuePtr(label));
|
692
|
-
|
693
|
-
if (NULL == cat) {
|
694
|
-
return Qnil;
|
695
|
-
}
|
696
|
-
return ID2SYM(rb_intern(cat->color->name));
|
697
|
-
}
|
698
|
-
|
699
|
-
/* Document-method: set_color
|
700
|
-
*
|
701
|
-
* call-seq: set_color(label, color_symbol)
|
702
|
-
*
|
703
|
-
* Sets color of the category associated with a label. Valid colors are
|
704
|
-
* :black, :red, :green, :yellow, :blue, :magenta, :cyan, :white, :gray,
|
705
|
-
* :dark_red, :dark_green, :brown, :dark_blue, :purple, and :dark_cyan.
|
706
|
-
*/
|
707
|
-
static VALUE
|
708
|
-
rlog_color_set(VALUE self, VALUE label, VALUE color) {
|
709
|
-
const char *label_str = StringValuePtr(label);
|
710
|
-
const char *color_name = StringValuePtr(color);
|
711
|
-
LogCat cat = log_cat_find(label_str);
|
712
|
-
Color c = find_color(color_name);
|
713
|
-
|
714
|
-
if (NULL == cat) {
|
715
|
-
rb_raise(rb_eArgError, "%s is not a valid category.", label_str);
|
716
|
-
}
|
717
|
-
if (NULL == c) {
|
718
|
-
rb_raise(rb_eArgError, "%s is not a valid color.", color_name);
|
719
|
-
}
|
720
|
-
cat->color = c;
|
721
|
-
|
722
|
-
return Qnil;
|
723
|
-
}
|
724
|
-
|
725
|
-
/* Document-method: state
|
726
|
-
*
|
727
|
-
* call-seq: state(label)
|
728
|
-
*
|
729
|
-
* Returns the current state of the category identified by the specified
|
730
|
-
* label.
|
731
|
-
*/
|
732
|
-
static VALUE
|
733
|
-
rlog_on_get(VALUE self, VALUE label) {
|
734
|
-
LogCat cat = log_cat_find(StringValuePtr(label));
|
735
|
-
|
736
|
-
if (NULL == cat) {
|
737
|
-
return Qfalse;
|
738
|
-
}
|
739
|
-
return cat->on ? Qtrue : Qfalse;
|
500
|
+
pthread_create(&the_log.thread, NULL, loop, NULL);
|
740
501
|
}
|
741
502
|
|
742
|
-
/* Document-method: set_state
|
743
|
-
*
|
744
|
-
* call-seq: set_state(label, state)
|
745
|
-
*
|
746
|
-
* Sets state of the category associated with a label.
|
747
|
-
*/
|
748
|
-
static VALUE
|
749
|
-
rlog_on_set(VALUE self, VALUE label, VALUE state) {
|
750
|
-
const char *label_str = StringValuePtr(label);
|
751
|
-
LogCat cat = log_cat_find(label_str);
|
752
|
-
|
753
|
-
if (NULL == cat) {
|
754
|
-
rb_raise(rb_eArgError, "%s is not a valid category.", label_str);
|
755
|
-
}
|
756
|
-
cat->on = (Qtrue == state);
|
757
|
-
|
758
|
-
return cat->on ? Qtrue : Qfalse;
|
759
|
-
}
|
760
|
-
|
761
|
-
/* Document-method: log
|
762
|
-
*
|
763
|
-
* call-seq: log[label] = msg
|
764
|
-
*
|
765
|
-
* Log a message in the specified category.
|
766
|
-
*/
|
767
|
-
static VALUE
|
768
|
-
rlog_log(VALUE self, VALUE label, VALUE msg) {
|
769
|
-
const char *label_str = StringValuePtr(label);
|
770
|
-
LogCat cat = log_cat_find(label_str);
|
771
|
-
|
772
|
-
if (NULL == cat) {
|
773
|
-
rb_raise(rb_eArgError, "%s is not a valid category.", label_str);
|
774
|
-
}
|
775
|
-
log_cat(cat, "%s", StringValuePtr(msg));
|
776
|
-
|
777
|
-
return Qnil;
|
778
|
-
}
|
779
|
-
|
780
|
-
/* Document-method: flush
|
781
|
-
*
|
782
|
-
* call-seq: flush
|
783
|
-
*
|
784
|
-
* Flush the log queue and write all entries to disk or the console. The call
|
785
|
-
* waits for the flush to complete or the timeout to be exceeded.
|
786
|
-
*/
|
787
|
-
static VALUE
|
788
|
-
rlog_flush(VALUE self, VALUE to) {
|
789
|
-
double timeout = NUM2DBL(to);
|
790
|
-
|
791
|
-
if (!log_flush(timeout)) {
|
792
|
-
rb_raise(rb_eStandardError, "timed out waiting for log flush.");
|
793
|
-
}
|
794
|
-
return Qnil;
|
795
|
-
}
|
796
|
-
|
797
|
-
/* Document-method: rotate
|
798
|
-
*
|
799
|
-
* call-seq: rotate()
|
800
|
-
*
|
801
|
-
* Rotate the log files.
|
802
|
-
*/
|
803
|
-
static VALUE
|
804
|
-
rlog_rotate(VALUE self) {
|
805
|
-
log_rotate();
|
806
|
-
return Qnil;
|
807
|
-
}
|
808
|
-
|
809
|
-
/* Document-method: console=
|
810
|
-
*
|
811
|
-
* call-seq: console=(on)
|
812
|
-
*
|
813
|
-
* If on then log output also goes to the console.
|
814
|
-
*/
|
815
|
-
static VALUE
|
816
|
-
rlog_console(VALUE self, VALUE on) {
|
817
|
-
the_log.console = (Qtrue == on);
|
818
|
-
return Qnil;
|
819
|
-
}
|
820
|
-
|
821
|
-
/* Document-method: classic
|
822
|
-
*
|
823
|
-
* call-seq: classic()
|
824
|
-
*
|
825
|
-
* Set the log format to classic format.
|
826
|
-
*/
|
827
|
-
static VALUE
|
828
|
-
rlog_classic(VALUE self) {
|
829
|
-
the_log.classic = true;
|
830
|
-
return Qnil;
|
831
|
-
}
|
832
|
-
|
833
|
-
/* Document-method: json
|
834
|
-
*
|
835
|
-
* call-seq: json()
|
836
|
-
*
|
837
|
-
* Set the log format to JSON format.
|
838
|
-
*/
|
839
|
-
static VALUE
|
840
|
-
rlog_json(VALUE self) {
|
841
|
-
the_log.classic = false;
|
842
|
-
return Qnil;
|
843
|
-
}
|
844
|
-
|
845
|
-
/* Document-method: max_size
|
846
|
-
*
|
847
|
-
* call-seq: max_size(size)
|
848
|
-
*
|
849
|
-
* Maximum log files size is reset.
|
850
|
-
*/
|
851
|
-
static VALUE
|
852
|
-
rlog_max_size(VALUE self, VALUE rmax) {
|
853
|
-
int max = FIX2INT(rmax);
|
854
|
-
|
855
|
-
if (1 <= max) {
|
856
|
-
the_log.max_size = max;
|
857
|
-
} else {
|
858
|
-
rb_raise(rb_eArgError, "max_size must be 1 or more.");
|
859
|
-
}
|
860
|
-
return Qnil;
|
861
|
-
}
|
862
|
-
|
863
|
-
/* Document-method: max_files
|
864
|
-
*
|
865
|
-
* call-seq: max_files(max)
|
866
|
-
*
|
867
|
-
* Maximum log files files is reset.
|
868
|
-
*/
|
869
|
-
static VALUE
|
870
|
-
rlog_max_files(VALUE self, VALUE rmax) {
|
871
|
-
int max = FIX2INT(rmax);
|
872
|
-
|
873
|
-
if (1 <= max || max < 100) {
|
874
|
-
the_log.max_files = max;
|
875
|
-
} else {
|
876
|
-
rb_raise(rb_eArgError, "max_files must be between 1 and 100.");
|
877
|
-
}
|
878
|
-
return Qnil;
|
879
|
-
}
|
880
|
-
|
881
|
-
|
882
|
-
/* Document-class: Agoo::Log
|
883
|
-
*
|
884
|
-
* An asynchronous and thread safe logger that includes file rollover and
|
885
|
-
* multiple logging categories. It is a feature based logger with a level
|
886
|
-
* overlay.
|
887
|
-
*/
|
888
503
|
void
|
889
|
-
log_init(
|
504
|
+
log_init() {
|
890
505
|
time_t t = time(NULL);
|
891
506
|
struct tm *tm = localtime(&t);
|
892
507
|
int qsize = 1024;
|
893
508
|
|
894
|
-
log_mod = rb_define_module_under(mod, "Log");
|
895
|
-
|
896
|
-
rb_define_module_function(log_mod, "configure", rlog_configure, 1);
|
897
|
-
rb_define_module_function(log_mod, "shutdown", rlog_shutdown, 0);
|
898
|
-
|
899
|
-
rb_define_module_function(log_mod, "error?", rlog_errorp, 0);
|
900
|
-
rb_define_module_function(log_mod, "warn?", rlog_warnp, 0);
|
901
|
-
rb_define_module_function(log_mod, "info?", rlog_infop, 0);
|
902
|
-
rb_define_module_function(log_mod, "debug?", rlog_debugp, 0);
|
903
|
-
|
904
|
-
rb_define_module_function(log_mod, "error", rlog_error, 1);
|
905
|
-
rb_define_module_function(log_mod, "warn", rlog_warn, 1);
|
906
|
-
rb_define_module_function(log_mod, "info", rlog_info, 1);
|
907
|
-
rb_define_module_function(log_mod, "debug", rlog_debug, 1);
|
908
|
-
|
909
|
-
// TBD maybe in a future version
|
910
|
-
//rb_define_module_function(log_mod, "register", rlog_register, 2);
|
911
|
-
|
912
|
-
rb_define_module_function(log_mod, "color", rlog_color_get, 1);
|
913
|
-
rb_define_module_function(log_mod, "set_color", rlog_color_set, 2);
|
914
|
-
|
915
|
-
rb_define_module_function(log_mod, "state", rlog_on_get, 1);
|
916
|
-
rb_define_module_function(log_mod, "set_state", rlog_on_set, 2);
|
917
|
-
|
918
|
-
rb_define_module_function(log_mod, "log", rlog_log, 2);
|
919
|
-
|
920
|
-
rb_define_module_function(log_mod, "flush", rlog_flush, 1);
|
921
|
-
rb_define_module_function(log_mod, "rotate", rlog_rotate, 0);
|
922
|
-
rb_define_module_function(log_mod, "console=", rlog_console, 1);
|
923
|
-
rb_define_module_function(log_mod, "classic", rlog_classic, 0);
|
924
|
-
rb_define_module_function(log_mod, "json", rlog_json, 0);
|
925
|
-
rb_define_module_function(log_mod, "max_size=", rlog_max_size, 1);
|
926
|
-
rb_define_module_function(log_mod, "max_files=", rlog_max_files, 1);
|
927
|
-
|
928
509
|
the_log.cats = NULL;
|
929
510
|
*the_log.dir = '\0';
|
930
511
|
the_log.file = NULL;
|
@@ -968,20 +549,3 @@ log_init(VALUE mod) {
|
|
968
549
|
|
969
550
|
log_start(false);
|
970
551
|
}
|
971
|
-
|
972
|
-
void
|
973
|
-
log_start(bool with_pid) {
|
974
|
-
if (NULL != the_log.file) {
|
975
|
-
fclose(the_log.file);
|
976
|
-
the_log.file = NULL;
|
977
|
-
// TBD close rsock and wsock
|
978
|
-
}
|
979
|
-
the_log.with_pid = with_pid;
|
980
|
-
if (with_pid && '\0' != *the_log.dir) {
|
981
|
-
if (0 != mkdir(the_log.dir, 0770) && EEXIST != errno) {
|
982
|
-
rb_raise(rb_eIOError, "Failed to create '%s'.", the_log.dir);
|
983
|
-
}
|
984
|
-
open_log_file();
|
985
|
-
}
|
986
|
-
pthread_create(&the_log.thread, NULL, loop, log);
|
987
|
-
}
|