Skip to content

Commit fe9d8e0

Browse files
committed
log: Add support for slf4j-style parameterised logging
1 parent 94655c8 commit fe9d8e0

File tree

1 file changed

+41
-29
lines changed

1 file changed

+41
-29
lines changed

src/log.q

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
// Logging Library
2-
// Copyright (c) 2015 - 2017 Sport Trades Ltd, 2020 Jaskirat Rajasansir
2+
// Copyright (c) 2015 - 2017 Sport Trades Ltd, 2020 - 2021 Jaskirat Rajasansir
33

44
// Documentation: https://github.com/BuaBook/kdb-common/wiki/log.q
55

6-
.require.lib each `util`type`time;
6+
.require.lib each `util`type`time`cargs;
77

88

99
/ Functions to determine which logger to use. The dictionary key is a symbol reference to the logger function if the
1010
/ value function is true.
1111
/ NOTE: .log.loggers.basic should always be last so it is the fallback if all others are not available
1212
.log.cfg.loggers:()!();
13-
.log.cfg.loggers[`.log.loggers.color]: { (not ""~getenv`KDB_COLORS) | `logColors in key .Q.opt .z.x };
14-
.log.cfg.loggers[`.log.loggers.syslog]:{ (not ""~getenv`KDB_LOG_SYSLOG) | `logSyslog in key .Q.opt .z.x };
15-
.log.cfg.loggers[`.log.loggers.json]: { (not ""~getenv`KDB_LOG_JSON) | `logJson in key .Q.opt .z.x };
13+
.log.cfg.loggers[`.log.loggers.color]: { (not ""~getenv`KDB_COLORS) | `logColors in key .cargs.get[] };
14+
.log.cfg.loggers[`.log.loggers.syslog]:{ (not ""~getenv`KDB_LOG_SYSLOG) | `logSyslog in key .cargs.get[] };
15+
.log.cfg.loggers[`.log.loggers.json]: { (not ""~getenv`KDB_LOG_JSON) | `logJson in key .cargs.get[] };
1616
.log.cfg.loggers[`.log.loggers.basic]: { 1b };
1717

1818

@@ -41,19 +41,23 @@
4141
.log.levels[`FATAL]:(-2i; 2i; "\033[4;31m");
4242

4343
/ Process identification
44-
/ @see .log.init
45-
.log.process:`;
44+
/ NOTE: If this is set prior to the library being initialised, it will not be overwritten during '.log.init'
45+
.log.process:"";
4646

4747

4848
.log.init:{
4949
if[.util.inDebugMode[];
5050
.log.level:`DEBUG;
5151
];
5252

53+
if[0 = count .log.process;
54+
.log.process:"pid-",string .z.i;
55+
];
56+
5357
/ setLogger calls setLevel
5458
.log.setLogger[];
5559

56-
.log.process:`$"pid-",string .z.i;
60+
.log.i.setInterfaceImplementations[];
5761
};
5862

5963

@@ -99,10 +103,6 @@
99103

100104
.log.level:newLevel;
101105

102-
if[`if in key .require.loadedLibs;
103-
.log.i.setInterfaceImplementations[];
104-
];
105-
106106
-1 "\nLogging enabled [ Level: ",string[.log.level]," ] [ Current Logger: `",string[.log.currentLogger]," ]\n";
107107
};
108108

@@ -118,45 +118,57 @@
118118
:(<=). key[.log.levels]?/: .log.level,level;
119119
};
120120

121+
/ String log formatter with slf4j-stule parameterised formatting
122+
/ @returns (StringList) List of log elements in string format
123+
/ @see http://www.slf4j.org/faq.html#logging_performance
124+
.log.strFormatter:{[lvl; message]
125+
if[0h = type message;
126+
message:"" sv ("{}" vs first message),'(.type.ensureString each 1_ message),enlist "";
127+
];
128+
129+
elems:(.time.today[]; .time.nowAsTime[]; lvl; .log.process; `system^.z.u; .z.w; message);
130+
elems:@[elems; where not .type.isString each elems; string];
131+
132+
:elems;
133+
};
134+
121135

122136
/ Basic logger
123137
.log.loggers.basic:{[fd;lvl;message]
124-
logElems:(.time.today[];.time.nowAsTime[];lvl;.log.process;`system^.z.u;.z.w;message);
125-
logElems:@[logElems; where not .type.isString each logElems; string];
126-
127-
fd " " sv logElems;
138+
fd " " sv .log.strFormatter[lvl; message];
128139
};
129140

130141
/ Logger with color highlighting of the level based on the configuration in .log.levels
131-
/ @see .log.levels
132-
/ @see .log.resetColor
133-
/ @see .log.loggers.basic
134142
.log.loggers.color:{[fd;lvl;message]
135143
lvl:(.log.levels[lvl]`color),string[lvl],.log.resetColor;
136-
137-
.log.loggers.basic[fd; lvl; message];
144+
fd " " sv .log.strFormatter[lvl; message];
138145
};
139146

140147
/ Non-color logger with the additional syslog priority prefix at the start of the log line. This is useful
141148
/ when capturing log output into systemd (via 'systemd-cat').
142-
/ NOTE: This function does not defer to '.log.loggers.basic' for logging
143-
/ @see .log.levels
144149
.log.loggers.syslog:{[fd;lvl;message]
145150
syslogLvl:"<",string[.log.levels[lvl]`syslog],">";
146-
147-
logElems:(syslogLvl;.time.today[];.time.nowAsTime[];lvl;.log.process;`system^.z.u;.z.w;message);
148-
logElems:@[logElems; where not .type.isString each logElems; string];
149-
150-
fd " " sv logElems;
151+
fd " " sv enlist[syslogLvl],.log.strFormatter[lvl; message];
151152
};
152153

153154
/ JSON logger
155+
/ NOTE: This logger does not do the slf4j-style parameterised replacement of the message but prints as the supplied list
154156
.log.loggers.json:{[fd;lvl;message]
155-
logElems:`date`time`level`processId`user`handle`message!(.time.today[];.time.nowAsTime[];lvl;.log.process;`system^.z.u;.z.w;message);
157+
logElems:`date`time`level`processId`user`handle`message!(.time.today[]; .time.nowAsTime[]; lvl; .log.process; `system^.z.u; .z.w; message);
156158
fd .j.j logElems;
157159
};
158160

161+
162+
/ Sets the interface functions for other kdb-common component and libraries if the interface 'if' library is defined
163+
/ in the current process
164+
/ @see .require.loadedLibs
165+
/ @see .if.setImplementationsFor
166+
/ @see .if.bindInterfacesFor
159167
.log.i.setInterfaceImplementations:{
168+
if[not `if in key .require.loadedLibs;
169+
:(::);
170+
];
171+
160172
allLevels:lower exec level from .log.levels;
161173

162174
ifFuncs:` sv/: `.log`if,/:allLevels;

0 commit comments

Comments
 (0)