Skip to content

Issue #44 Create Log Formatter and implement JSONL Structured Logger

Adds a log formatter object similar to the Python logging module formatter - https://docs.python.org/3/library/logging.html#formatter-objects

The default formatter implements the current HSE datetime and log format so there are no changes to existing log layouts. To change the log format explicitly call Create Formatter.vi or Create JSONLFormatter.vi and set Handler format using the Set Formatter.vi method.

The main changes to the current logging pipeline are in Handle LogRec.vi. Instead of formatting the log record internally in this function it now calls Format LogRecord.vi before writing to file OR generating a user event.

Output from Formatter (UserEventHandler):

4: HSE-Logger: 2023-11-21 19:42:53 - CRITICAL - Test CRITICAL - Logging with Helper-VIs.vi - -999 - Hello World, this is a CRITICAL error.
3: HSE-Logger: 2023-11-21 19:42:37 - ERROR   - Test ERROR - Logging with Helper-VIs.vi - -999 - Hello World, this is an error.
2: HSE-Logger: 2023-11-21 19:42:10 - WARNING - Test WARNING - Logging with Helper-VIs.vi - -111 - 
1: HSE-Logger: 2023-11-21 19:41:49 - INFO    - Test INFO - Logging with Helper-VIs.vi - 0 - 
0: HSE-Logger: 2023-11-21 19:41:35 - DEBUG   - Test DEBUG - Logging with Helper-VIs.vi - 0 - 

Output from JSONL Formatter (https://jsonlines.org/) (FileHandler):

{"time":"2023-11-21 19:41:35","log_level":"DEBUG","message":"Test DEBUG","call_chain":"Logging with Helper-VIs.vi","error_code":"0","source":""}
{"time":"2023-11-21 19:41:49","log_level":"INFO","message":"Test INFO","call_chain":"Logging with Helper-VIs.vi","error_code":"0","source":""}
{"time":"2023-11-21 19:42:10","log_level":"WARNING","message":"Test WARNING","call_chain":"Logging with Helper-VIs.vi","error_code":"-111","source":""}
{"time":"2023-11-21 19:42:37","log_level":"ERROR","message":"Test ERROR","call_chain":"Logging with Helper-VIs.vi","error_code":"-999","source":"Hello World, this is an error."}
{"time":"2023-11-21 19:42:53","log_level":"CRITICAL","message":"Test CRITICAL","call_chain":"Logging with Helper-VIs.vi","error_code":"-999","source":"Hello World, this is a CRITICAL error."}

Error output from JSONL Formatter with retain all errors option (LabVIEW 2020).

{"time":"2023-11-27 12:01:56","log_level":"ERROR","message":"Error message.","call_chain":"Untitled 1","error_code":"0","source":"ERROR 0"}
{"time":"2023-11-27 12:01:56","log_level":"ERROR","message":"Error message.","call_chain":"Untitled 1","error_code":"1","source":"<JSONErrorMultiple_1.0>[{\n    \"status\": true,\n    \"code\": 1,\n    \"source\": \"ERROR 1\"\n},{\n    \"status\": true,\n    \"code\": 0,\n    \"source\": \"ERROR 0\"\n}]"}
{"time":"2023-11-27 12:01:56","log_level":"ERROR","message":"Error message.","call_chain":"Untitled 1","error_code":"2","source":"<JSONErrorMultiple_1.0>[{\n    \"status\": true,\n    \"code\": 2,\n    \"source\": \"ERROR 2\"\n},{\n    \"status\": true,\n    \"code\": 1,\n    \"source\": \"ERROR 1\"\n},{\n    \"status\": true,\n    \"code\": 0,\n    \"source\": \"ERROR 0\"\n}]"}
{"time":"2023-11-27 12:01:56","log_level":"ERROR","message":"Error message.","call_chain":"Untitled 1","error_code":"3","source":"<JSONErrorMultiple_1.0>[{\n    \"status\": true,\n    \"code\": 3,\n    \"source\": \"ERROR 3\"\n},{\n    \"status\": true,\n    \"code\": 2,\n    \"source\": \"ERROR 2\"\n},{\n    \"status\": true,\n    \"code\": 1,\n    \"source\": \"ERROR 1\"\n},{\n    \"status\": true,\n    \"code\": 0,\n    \"source\": \"ERROR 0\"\n}]"}
{"time":"2023-11-27 12:01:56","log_level":"ERROR","message":"Error message.","call_chain":"Untitled 1","error_code":"4","source":"<JSONErrorMultiple_1.0>[{\n    \"status\": true,\n    \"code\": 4,\n    \"source\": \"ERROR 4\"\n},{\n    \"status\": true,\n    \"code\": 3,\n    \"source\": \"ERROR 3\"\n},{\n    \"status\": true,\n    \"code\": 2,\n    \"source\": \"ERROR 2\"\n},{\n    \"status\": true,\n    \"code\": 1,\n    \"source\": \"ERROR 1\"\n},{\n    \"status\": true,\n    \"code\": 0,\n    \"source\": \"ERROR 0\"\n}]"}

Other decisions of note:

  • JSONL Formatter uses the built in Flatten To JSON.vi so this MR does not add any external dependencies.
  • I updated the padding for Log Level to a width of 8 in the default formatter as I noticed that CRITICAL is 8 characters.

Example updated to include the new Formatter: image

Edited by Paul O'Neill

Merge request reports