mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-15 15:24:52 +09:00
Split logs by date
Move the default location of the log files into a configurable logs folder and split the written logs up by UTC date to more easily allow deleting of old logs to be performed. The log rotation is implemented by winston-daily-rotate-file. The old log format will automatically be migrated to the new format and location if the target folder for the new logs don't yet exists.
This commit is contained in:
1 parent
200ccf8e06
commit
fd1f3329bd
5 files changed
+125
-9
No files matched your search
@@ -1,4 +1,7 @@
|
||||
"use strict";
|
||||
const events = require("events");
|
||||
const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
const winston = require("winston");
|
||||
const Transport = require("winston-transport");
|
||||
const { LEVEL, MESSAGE } = require("triple-beam");
|
||||
@@ -6,6 +9,7 @@ const chalk = require("chalk");
|
||||
|
||||
const libLink = require("./link");
|
||||
const libErrors = require("./errors");
|
||||
const libStream = require("./stream");
|
||||
|
||||
|
||||
/**
|
||||
@@ -121,10 +125,67 @@ class LinkTransport extends Transport {
|
||||
}
|
||||
}
|
||||
|
||||
async function migrateLogs(log, directory, pattern) {
|
||||
const dateRegExp = /^\d{4}-\d{2}-\d{2}/;
|
||||
let lineStream = new libStream.LineSplitter({ readableObjectMode: true });
|
||||
let fileStream = fs.createReadStream(log);
|
||||
fileStream.pipe(lineStream);
|
||||
|
||||
let currentDate = null;
|
||||
let output = null;
|
||||
|
||||
async function switchOutput(newOutputPath) {
|
||||
if (output) {
|
||||
output.end();
|
||||
await events.once(output, "close");
|
||||
}
|
||||
|
||||
output = fs.createWriteStream(newOutputPath, { flags: "ax" });
|
||||
try {
|
||||
await events.once(output, "open");
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`writing ${newOutputPath}`);
|
||||
} catch (err) {
|
||||
if (err.code === "EEXIST") {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(`Discarding logs for ${newDate} due to target logfile already existing`);
|
||||
output = null;
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for await (let line of lineStream) {
|
||||
let info = {};
|
||||
try {
|
||||
info = JSON.parse(line);
|
||||
} catch (err) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
if (typeof info.timestamp === "string" && dateRegExp.test(info.timestamp)) {
|
||||
let newDate = info.timestamp.slice(0, 10);
|
||||
// Only update date forward in time.
|
||||
if (newDate !== currentDate && (!currentDate || newDate > currentDate)) {
|
||||
await switchOutput(path.join(directory, pattern.replace("%DATE%", newDate)));
|
||||
currentDate = newDate;
|
||||
}
|
||||
}
|
||||
|
||||
if (output) {
|
||||
if (!output.write(Buffer.concat([line, Buffer.from("\n")]))) {
|
||||
await events.once(output, "drain");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
TerminalFormat,
|
||||
LinkTransport,
|
||||
migrateLogs,
|
||||
|
||||
// for testing only
|
||||
_formatServerOutput: formatServerOutput,
|
||||
|
||||
@@ -22,6 +22,7 @@ const setBlocking = require("set-blocking");
|
||||
const yargs = require("yargs");
|
||||
const util = require("util");
|
||||
const winston = require("winston");
|
||||
require("winston-daily-rotate-file");
|
||||
const jwt = require("jsonwebtoken");
|
||||
|
||||
// homebrew modules
|
||||
@@ -189,6 +190,12 @@ async function initialize() {
|
||||
choices: ["none"].concat(Object.keys(levels)),
|
||||
type: "string",
|
||||
})
|
||||
.option("log-directory", {
|
||||
nargs: 1,
|
||||
describe: "Directory to place logs in",
|
||||
default: "logs",
|
||||
type: "string",
|
||||
})
|
||||
.option("config", {
|
||||
nargs: 1,
|
||||
describe: "master config file to use",
|
||||
@@ -227,20 +234,45 @@ async function initialize() {
|
||||
.argv
|
||||
;
|
||||
|
||||
{
|
||||
// Migration from alpha-10 single file logs, note that we can't use
|
||||
// the logger here as it's not initalized yet.
|
||||
/* eslint-disable no-console */
|
||||
let clusterLogDirectory = path.join(parameters.args.logDirectory, "cluster");
|
||||
if (!await fs.pathExists(clusterLogDirectory) && await fs.pathExists("cluster.log")) {
|
||||
console.log("Migrating cluster log...");
|
||||
await fs.ensureDir(clusterLogDirectory);
|
||||
await libLoggingUtils.migrateLogs("cluster.log", clusterLogDirectory, "cluster-%DATE%.log");
|
||||
console.log("Migration complete, you should delete cluster.log now");
|
||||
}
|
||||
|
||||
let masterLogDirectory = path.join(parameters.args.logDirectory, "master");
|
||||
if (!await fs.pathExists(masterLogDirectory) && await fs.pathExists("master.log")) {
|
||||
console.log("Migrating master log...");
|
||||
await fs.ensureDir(masterLogDirectory);
|
||||
await libLoggingUtils.migrateLogs("master.log", masterLogDirectory, "master-%DATE%.log");
|
||||
console.log("Migration complete, you should delete master.log now");
|
||||
}
|
||||
/* eslint-enable no-console */
|
||||
}
|
||||
|
||||
// Combined log stream of the whole cluster.
|
||||
parameters.clusterLogger = winston.createLogger({
|
||||
format: winston.format.json(),
|
||||
level: "verbose",
|
||||
levels,
|
||||
});
|
||||
parameters.clusterLogger.add(new winston.transports.File({
|
||||
filename: "cluster.log",
|
||||
parameters.clusterLogger.add(new winston.transports.DailyRotateFile({
|
||||
filename: "cluster-%DATE%.log",
|
||||
utc: true,
|
||||
dirname: path.join(parameters.args.logDirectory, "cluster"),
|
||||
}));
|
||||
|
||||
// Log stream for the master server.
|
||||
logger.add(new winston.transports.File({
|
||||
logger.add(new winston.transports.DailyRotateFile({
|
||||
format: winston.format.json(),
|
||||
filename: "master.log",
|
||||
filename: "master-%DATE%.log",
|
||||
dirname: path.join(parameters.args.logDirectory, "master"),
|
||||
}));
|
||||
logger.add(new winston.transports.Stream({
|
||||
stream: parameters.clusterLogger,
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"jszip": "^3.2.2",
|
||||
"set-blocking": "^2.0.0",
|
||||
"winston": "^3.3.3",
|
||||
"winston-daily-rotate-file": "^4.5.5",
|
||||
"ws": "^7.2.3",
|
||||
"yargs": "^14.2.0"
|
||||
},
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"pidusage": "^2.0.18",
|
||||
"set-blocking": "^2.0.0",
|
||||
"winston": "^3.3.3",
|
||||
"winston-daily-rotate-file": "^4.5.5",
|
||||
"yargs": "^14.2.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
||||
+26
-5
@@ -23,6 +23,7 @@ const phin = require("phin");
|
||||
const util = require("util");
|
||||
const version = require("./package").version;
|
||||
const winston = require("winston");
|
||||
require("winston-daily-rotate-file");
|
||||
|
||||
// internal libraries
|
||||
const libFileOps = require("@clusterio/lib/file_ops");
|
||||
@@ -1734,6 +1735,12 @@ async function startSlave() {
|
||||
choices: ["none"].concat(Object.keys(levels)),
|
||||
type: "string",
|
||||
})
|
||||
.option("log-directory", {
|
||||
nargs: 1,
|
||||
describe: "Directory to place logs in",
|
||||
default: "logs",
|
||||
type: "string",
|
||||
})
|
||||
.option("config", {
|
||||
nargs: 1,
|
||||
describe: "slave config file to use",
|
||||
@@ -1754,11 +1761,25 @@ async function startSlave() {
|
||||
.argv
|
||||
;
|
||||
|
||||
logger.add(new winston.transports.File({
|
||||
format: winston.format.combine(
|
||||
winston.format.json(),
|
||||
),
|
||||
filename: "slave.log",
|
||||
{
|
||||
// Migration from alpha-10 single file logs, note that we can't use
|
||||
// the logger here as it's not initalized yet.
|
||||
/* eslint-disable no-console */
|
||||
let slaveLogDirectory = path.join(args.logDirectory, "slave");
|
||||
if (!await fs.pathExists(slaveLogDirectory) && await fs.pathExists("slave.log")) {
|
||||
console.log("Migrating slave log...");
|
||||
await fs.ensureDir(slaveLogDirectory);
|
||||
await libLoggingUtils.migrateLogs("slave.log", slaveLogDirectory, "slave-%DATE%.log");
|
||||
console.log("Migration complete, you should delete slave.log now");
|
||||
}
|
||||
/* eslint-enable no-console */
|
||||
}
|
||||
|
||||
logger.add(new winston.transports.DailyRotateFile({
|
||||
format: winston.format.json(),
|
||||
filename: "slave-%DATE%.log",
|
||||
utc: true,
|
||||
dirname: path.join(args.logDirectory, "slave"),
|
||||
}));
|
||||
if (args.logLevel !== "none") {
|
||||
logger.add(new ConsoleTransport({
|
||||
|
||||
Reference in new issue
Block a user