forked from mairas/signalk-data-logger
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
146 lines (123 loc) · 3.6 KB
/
index.js
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
const Bacon = require("baconjs");
const debug = require("debug")("signalk:signalk-data-logger");
const util = require("util");
const _ = require('lodash')
const path = require('path')
const fs = require('fs')
const { spawn } = require('child_process')
/*
Signal K server plugin to log Signal K deltas to flat files.
Features:
- Basic logging
- Configurable log directory
- Splitting per hour
TODO:
- Exclude filtering
- Include filtering
- Throttling
*/
module.exports = function(app) {
var plugin = {};
var unsubscribes = [];
var logDir = ""
var logFileName = "data_log.json"
var logRotationInterval = 600
plugin.id = "sk-data-logger"
plugin.name = "Signal K delta logger"
plugin.description = "Log Signal K delta objects to compressed flat files."
plugin.schema = {
type: "object",
title: "Data logging to flat files",
description: "Log Signal K data as delta objects into flat files.",
properties: {
logdir: {
type: 'string',
title: 'Data log file directory',
default: '/home/pi/sk-delta-logs'
},
interval: {
type: 'number',
title: 'Log rotation interval (in seconds). Value of zero disables log rotation.',
default: 600
}
}
}
plugin.start = function (options) {
if (typeof options.logdir === 'undefined') {
app.setProviderStatus('Log directory not defined, plugin disabled')
return
}
logDir = options.logdir
logRotationInterval = options.interval
if (!fs.existsSync(logDir)) {
// attempt creating the log directory
try {
fs.mkdirSync(logDir)
} catch (error) {
app.setProviderStatus(`Unable to create log directory ${logDir}, plugin disabled`)
return
}
}
// compress the old leftover logfile, if any
const logMetaFileName = path.join(logDir, '.current_log_file')
if (fs.existsSync(logMetaFileName)) {
app.debug("meta file exists")
const oldLogFile = fs.readFileSync(logMetaFileName).toString()
if (fs.existsSync(path.join(logDir, oldLogFile))) {
compressLogFile(logDir, oldLogFile)
}
}
// create a new logfile
rotateLogFile(new Date())
if (logRotationInterval > 0) {
setInterval(() => {
rotateLogFile(new Date(), true)
},
logRotationInterval * 1000
)
}
app.signalk.on('delta', (delta) => {
try {
writeDelta(delta)
} catch ( err ) {
console.log(err)
}
})
}
plugin.stop = function () {
// compress the log file
rotateLogFile(new Date(), true)
// supposedly no need to unsubscribe a delta handler?
// plugin.unsubscribes.forEach(f => f())
// unsubscribes = []
}
return plugin
function writeDelta(delta) {
fs.appendFile(
path.join(logDir, logFileName),
JSON.stringify(delta).concat("\n"), (err) => {
if (err) throw err;
}
)
}
function compressLogFile(logDir, logFileName) {
let logPath = path.join(logDir, logFileName)
const gzip = spawn('gzip', [logPath])
gzip.on('close', (code) => {
if (code !== 0) {
console.log(`Compressing file ${logPath} failed with exit code ${code}`)
}
})
}
function rotateLogFile(time, compressPrevious = false) {
// update the log filename
const oldLogFileName = logFileName
logFileName = "sk-delta-log.".concat(time.toISOString()).concat('.log')
// gzip the old logfile
if (compressPrevious) {
compressLogFile(logDir, oldLogFileName)
}
// keep track of the current log file
fs.writeFileSync(path.join(logDir, '.current_log_file'), logFileName)
}
}