-
Notifications
You must be signed in to change notification settings - Fork 1
/
logstash.lisp
91 lines (80 loc) · 3.22 KB
/
logstash.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
;; -*- lisp -*-
(in-package :a-cl-logger)
(cl-interpol:enable-interpol-syntax)
(defclass node-logstash-appender (stream-log-appender)
((log-stash-type :accessor log-stash-type :initarg :log-stash-type :initform nil)
(log-stash-server
:accessor log-stash-server :initarg :log-stash-server
:initform nil))
(:default-initargs :formatter 'json-formatter))
(defun zeromq-send-data (json &key server &aux connected)
"Push a message to the logstash zmq"
(zmq:with-context (ctx 1)
(zmq:with-socket (socket ctx :push)
(unwind-protect
(progn
(setf connected (zerop (zmq:connect socket server)))
(zmq:with-msg-init-data (msg json)
(zmq:msg-send msg socket (list :dontwait))))
(when connected
;; Disconnecting causes all messages to not flow, for some reason
;; I believe we will blcok on with-socket to close until all messages
;; are sent which this seems to bypass?
;; (zmq:disconnect socket server)
)))))
(defmethod append-message ((appender node-logstash-appender)
message)
(setf message
(copy-messsage
message
:type (princ-to-string
(or (log-stash-type appender)
(name (logger message))))))
(let ((out (with-output-to-string (json)
(format-message
appender
(formatter appender)
message
json))))
; (format t "~%SENDING ZMQ MSQ: ~A~%" out)
(zeromq-send-data out :server (log-stash-server appender))))
(defun ensure-node-logstash-appender (logger
&key log-stash-server log-stash-type
(type 'node-logstash-appender))
(require-logger! logger)
(alexandria:when-let
(a (find-appender
logger
:type type
:predicate (lambda (a) (string-equal (log-stash-server a)
log-stash-server))))
(return-from ensure-node-logstash-appender a))
(let ((new (make-instance type
:log-stash-type log-stash-type
:log-stash-server log-stash-server)))
(push new (appenders logger))
new))
(defun only-logstash-appends (c)
(unless (typep (appender c) 'node-logstash-appender)
(abort c)))
(defun no-logstash-appends (c)
(when (typep (appender c) 'node-logstash-appender)
(abort c)))
(defmacro without-logstashing (() &body body)
`(handler-bind ((appending-message 'no-logstash-appends))
,@body))
(defmacro with-logstashing-only (() &body body)
`(handler-bind ((appending-message 'only-logstash-appends))
,@body))
(defmacro with-concatenated-logstash-logs ((&key (logger *root-logger*)
(level '+info+))
&body body)
(alexandria:with-unique-names (lg logs rtn)
`(let ( (,lg ,logger) ,logs ,rtn )
(without-logstashing ()
(with-logged-output-to-place (,lg ,logs)
(setf ,rtn (multiple-value-list
(progn ,@body)))))
(with-logstashing-only ()
(do-log ,lg ,level ,logs))
(apply #'values ,rtn))))