Update spdlog (#11)
* Update spdlog
* Fix logger functions
* 💄
* Add back sync logger, refactor
* Use helper function, add Windows define
* Fix build on Windows
* Add ifdef
* Remove setFlushEvery
This commit is contained in:
Родитель
9c227dd15c
Коммит
4fc6c51bf9
|
@ -31,6 +31,7 @@ bower_components
|
||||||
|
|
||||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||||
build
|
build
|
||||||
|
bin
|
||||||
|
|
||||||
# Dependency directories
|
# Dependency directories
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
|
@ -16,6 +16,11 @@
|
||||||
'xcode_settings': {
|
'xcode_settings': {
|
||||||
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES'
|
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES'
|
||||||
}
|
}
|
||||||
|
}],
|
||||||
|
['OS=="win"', {
|
||||||
|
'defines': [
|
||||||
|
'SPDLOG_WCHAR_FILENAMES'
|
||||||
|
]
|
||||||
}]
|
}]
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 560df2878ad308b27873b3cc5e810635d69cfad6
|
Subproject commit 100f30043f33277122e0991c83845a2617172ffd
|
|
@ -4,13 +4,14 @@
|
||||||
* license information.
|
* license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
export const version: string;
|
export const version: number;
|
||||||
export function setAsyncMode(bufferSize: number, flushInterval: number): void;
|
export function setLevel(level: number);
|
||||||
export function createRotatingLogger(name: string, filename: string, filesize: number, filecount: number): RotatingLogger;
|
export function shutdown();
|
||||||
export function createRotatingLoggerAsync(name: string, filename: string, filesize: number, filecount: number): Promise<RotatingLogger>;
|
export function createRotatingLogger(name: string, filename: string, filesize: number, filecount: number): Promise<Logger>;
|
||||||
|
export function createAsyncRotatingLogger(name: string, filename: string, filesize: number, filecount: number): Promise<Logger>;
|
||||||
|
|
||||||
export class RotatingLogger {
|
export class Logger {
|
||||||
constructor(name: string, filename: string, filesize: number, filecount: number);
|
constructor(loggerType: "rotating" | "rotating_async" | "stdout_async", name: string, filename: string, filesize: number, filecount: number);
|
||||||
|
|
||||||
trace(message: string): void;
|
trace(message: string): void;
|
||||||
debug(message: string): void;
|
debug(message: string): void;
|
||||||
|
@ -18,7 +19,9 @@ export class RotatingLogger {
|
||||||
warn(message: string): void;
|
warn(message: string): void;
|
||||||
error(message: string): void;
|
error(message: string): void;
|
||||||
critical(message: string): void;
|
critical(message: string): void;
|
||||||
|
getLevel(): number;
|
||||||
setLevel(level: number): void;
|
setLevel(level: number): void;
|
||||||
|
setPattern(pattern: string): void;
|
||||||
clearFormatters(): void;
|
clearFormatters(): void;
|
||||||
/**
|
/**
|
||||||
* A synchronous operation to flush the contents into file
|
* A synchronous operation to flush the contents into file
|
||||||
|
|
29
index.js
29
index.js
|
@ -3,37 +3,30 @@ const mkdirp = require('mkdirp');
|
||||||
const spdlog = require('bindings')('spdlog');
|
const spdlog = require('bindings')('spdlog');
|
||||||
|
|
||||||
exports.version = spdlog.version;
|
exports.version = spdlog.version;
|
||||||
exports.setAsyncMode = spdlog.setAsyncMode;
|
|
||||||
exports.setLevel = spdlog.setLevel;
|
exports.setLevel = spdlog.setLevel;
|
||||||
|
exports.shutdown = spdlog.shutdown;
|
||||||
exports.Logger = spdlog.Logger;
|
exports.Logger = spdlog.Logger;
|
||||||
|
|
||||||
class RotatingLogger extends spdlog.Logger {
|
function createRotatingLogger(name, filepath, maxFileSize, maxFiles) {
|
||||||
constructor(name, filename, maxFileSize, maxFiles) {
|
return createLogger('rotating', name, filepath, maxFileSize, maxFiles);
|
||||||
if (path.isAbsolute(filename)) {
|
|
||||||
mkdirp.sync(path.dirname(filename));
|
|
||||||
}
|
|
||||||
|
|
||||||
super('rotating', name, filename, maxFileSize, maxFiles);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createRotatingLoggerAsync(name, filepath, maxFileSize, maxFiles) {
|
function createAsyncRotatingLogger(name, filepath, maxFileSize, maxFiles) {
|
||||||
|
return createLogger('rotating_async', name, filepath, maxFileSize, maxFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createLogger(loggerType, name, filepath, maxFileSize, maxFiles) {
|
||||||
return new Promise((c, e) => {
|
return new Promise((c, e) => {
|
||||||
const dirname = path.dirname(filepath);
|
const dirname = path.dirname(filepath);
|
||||||
mkdirp(dirname, err => {
|
mkdirp(dirname, err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
e(err);
|
e(err);
|
||||||
} else {
|
} else {
|
||||||
c(createRotatingLogger(name, filepath, maxFileSize, maxFiles));
|
c(new spdlog.Logger(loggerType, name, filepath, maxFileSize, maxFiles));
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function createRotatingLogger(name, filepath, maxFileSize, maxFiles) {
|
|
||||||
return new spdlog.Logger('rotating', name, filepath, maxFileSize, maxFiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.createRotatingLoggerAsync = createRotatingLoggerAsync;
|
|
||||||
exports.createRotatingLogger = createRotatingLogger;
|
exports.createRotatingLogger = createRotatingLogger;
|
||||||
exports.RotatingLogger = RotatingLogger;
|
exports.createAsyncRotatingLogger = createAsyncRotatingLogger;
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -4,22 +4,16 @@
|
||||||
* license information.
|
* license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <spdlog/async.h>
|
||||||
|
#include <spdlog/sinks/rotating_file_sink.h>
|
||||||
|
#include <spdlog/sinks/stdout_sinks.h>
|
||||||
|
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
NAN_METHOD(setAsyncMode) {
|
#if defined(_WIN32)
|
||||||
if (!info[0]->IsNumber()) {
|
#include <codecvt>
|
||||||
return Nan::ThrowError(Nan::Error("Provide queue size as first parameter"));
|
#endif
|
||||||
}
|
|
||||||
if (!info[1]->IsNumber()) {
|
|
||||||
return Nan::ThrowError(Nan::Error(
|
|
||||||
"Provide a flush interval in milliseconds as second parameter"));
|
|
||||||
}
|
|
||||||
|
|
||||||
spdlog::set_async_mode(
|
|
||||||
Nan::To<int64_t>(info[0]).FromJust(),
|
|
||||||
spdlog::async_overflow_policy::block_retry, nullptr,
|
|
||||||
std::chrono::milliseconds(Nan::To<int64_t>(info[1]).FromJust()));
|
|
||||||
}
|
|
||||||
|
|
||||||
NAN_METHOD(setLevel) {
|
NAN_METHOD(setLevel) {
|
||||||
if (!info[0]->IsNumber()) {
|
if (!info[0]->IsNumber()) {
|
||||||
|
@ -56,12 +50,13 @@ NAN_METHOD(setLevel) {
|
||||||
spdlog::set_level(level);
|
spdlog::set_level(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NAN_METHOD(shutdown) {
|
||||||
|
spdlog::shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
Nan::Persistent<v8::Function> Logger::constructor;
|
Nan::Persistent<v8::Function> Logger::constructor;
|
||||||
|
|
||||||
NAN_MODULE_INIT(Logger::Init) {
|
NAN_MODULE_INIT(Logger::Init) {
|
||||||
spdlog::set_async_mode(8192, spdlog::async_overflow_policy::block_retry,
|
|
||||||
nullptr, std::chrono::seconds(1));
|
|
||||||
|
|
||||||
v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
|
v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
|
||||||
tpl->SetClassName(Nan::New("Logger").ToLocalChecked());
|
tpl->SetClassName(Nan::New("Logger").ToLocalChecked());
|
||||||
tpl->InstanceTemplate()->SetInternalFieldCount(1);
|
tpl->InstanceTemplate()->SetInternalFieldCount(1);
|
||||||
|
@ -111,7 +106,7 @@ NAN_METHOD(Logger::New) {
|
||||||
const std::string name = *Nan::Utf8String(info[0]);
|
const std::string name = *Nan::Utf8String(info[0]);
|
||||||
std::shared_ptr<spdlog::logger> logger;
|
std::shared_ptr<spdlog::logger> logger;
|
||||||
|
|
||||||
if (name == "rotating") {
|
if (name == "rotating" || name == "rotating_async") {
|
||||||
if (!info[1]->IsString() || !info[2]->IsString()) {
|
if (!info[1]->IsString() || !info[2]->IsString()) {
|
||||||
return Nan::ThrowError(
|
return Nan::ThrowError(
|
||||||
Nan::Error("Provide the log name and file name"));
|
Nan::Error("Provide the log name and file name"));
|
||||||
|
@ -133,12 +128,18 @@ NAN_METHOD(Logger::New) {
|
||||||
const std::string fileName = *Nan::Utf8String(info[2]);
|
const std::string fileName = *Nan::Utf8String(info[2]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
logger = spdlog::rotating_logger_mt(
|
if (logName == "rotating_async") {
|
||||||
|
logger = spdlog::rotating_logger_st<spdlog::async_factory>(
|
||||||
|
logName, fileName, Nan::To<int64_t>(info[3]).FromJust(),
|
||||||
|
Nan::To<int64_t>(info[4]).FromJust());
|
||||||
|
} else {
|
||||||
|
logger = spdlog::rotating_logger_st(
|
||||||
logName, fileName, Nan::To<int64_t>(info[3]).FromJust(),
|
logName, fileName, Nan::To<int64_t>(info[3]).FromJust(),
|
||||||
Nan::To<int64_t>(info[4]).FromJust());
|
Nan::To<int64_t>(info[4]).FromJust());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
logger = spdlog::stdout_logger_mt(name);
|
logger = spdlog::stdout_logger_st<spdlog::async_factory>(name);
|
||||||
}
|
}
|
||||||
Logger *obj = new Logger(logger);
|
Logger *obj = new Logger(logger);
|
||||||
obj->Wrap(info.This());
|
obj->Wrap(info.This());
|
||||||
|
|
11
src/logger.h
11
src/logger.h
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
NAN_METHOD(setAsyncMode);
|
|
||||||
NAN_METHOD(setLevel);
|
NAN_METHOD(setLevel);
|
||||||
|
NAN_METHOD(shutdown);
|
||||||
|
|
||||||
class Logger : public Nan::ObjectWrap {
|
class Logger : public Nan::ObjectWrap {
|
||||||
public:
|
public:
|
||||||
|
@ -52,9 +52,12 @@ class Logger : public Nan::ObjectWrap {
|
||||||
};
|
};
|
||||||
|
|
||||||
class VoidFormatter : public spdlog::formatter {
|
class VoidFormatter : public spdlog::formatter {
|
||||||
void format(spdlog::details::log_msg &msg) override {
|
void format(const spdlog::details::log_msg &msg, spdlog::memory_buf_t &dest) override {
|
||||||
msg.formatted << fmt::StringRef(msg.raw.data(), msg.raw.size());
|
spdlog::details::fmt_helper::append_string_view(msg.payload, dest);
|
||||||
msg.formatted.write("", -1);
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<spdlog::formatter> clone() const override {
|
||||||
|
return spdlog::details::make_unique<VoidFormatter>();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
11
src/main.cc
11
src/main.cc
|
@ -8,14 +8,9 @@
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
NAN_MODULE_INIT(Init) {
|
NAN_MODULE_INIT(Init) {
|
||||||
Nan::Set(target, Nan::New("version").ToLocalChecked(),
|
Nan::Set(target, Nan::New("version").ToLocalChecked(), Nan::New(SPDLOG_VERSION));
|
||||||
Nan::New(SPDLOG_VERSION).ToLocalChecked());
|
Nan::SetMethod(target, "setLevel", setLevel);
|
||||||
Nan::Set(target, Nan::New("setAsyncMode").ToLocalChecked(),
|
Nan::SetMethod(target, "shutdown", shutdown);
|
||||||
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(setAsyncMode))
|
|
||||||
.ToLocalChecked());
|
|
||||||
Nan::Set(target, Nan::New("setLevel").ToLocalChecked(),
|
|
||||||
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(setLevel))
|
|
||||||
.ToLocalChecked());
|
|
||||||
|
|
||||||
Logger::Init(target);
|
Logger::Init(target);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ suite('API', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
suiteTeardown(() => {
|
suiteTeardown(() => {
|
||||||
|
spdlog.shutdown();
|
||||||
filesToDelete.forEach(file => {
|
filesToDelete.forEach(file => {
|
||||||
if (fs.existsSync(file)) {
|
if (fs.existsSync(file)) {
|
||||||
fs.unlinkSync(file);
|
fs.unlinkSync(file);
|
||||||
|
@ -53,20 +54,8 @@ suite('API', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('is loaded', function () {
|
test('Version', function () {
|
||||||
const spdloghPath = path.join(__dirname, '..', 'deps', 'spdlog', 'include', 'spdlog', 'common.h');
|
assert.strictEqual(spdlog.version, 10805);
|
||||||
const contents = fs.readFileSync(spdloghPath, 'utf8');
|
|
||||||
const version = /SPDLOG_VERSION "([\d\.]+)"/.exec(contents)[1];
|
|
||||||
|
|
||||||
assert.equal(spdlog.version, version);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('is loaded', function () {
|
|
||||||
const spdloghPath = path.join(__dirname, '..', 'deps', 'spdlog', 'include', 'spdlog', 'common.h');
|
|
||||||
const contents = fs.readFileSync(spdloghPath, 'utf8');
|
|
||||||
const version = /SPDLOG_VERSION "([\d\.]+)"/.exec(contents)[1];
|
|
||||||
|
|
||||||
assert.equal(spdlog.version, version);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Logger is present', function () {
|
test('Logger is present', function () {
|
||||||
|
@ -133,25 +122,25 @@ suite('API', function () {
|
||||||
test('set level', async function () {
|
test('set level', async function () {
|
||||||
testObject = await aTestObject(logFile);
|
testObject = await aTestObject(logFile);
|
||||||
testObject.setLevel(0);
|
testObject.setLevel(0);
|
||||||
assert.equal(testObject.getLevel(), 0);
|
assert.strictEqual(testObject.getLevel(), 0);
|
||||||
|
|
||||||
testObject.setLevel(1);
|
testObject.setLevel(1);
|
||||||
assert.equal(testObject.getLevel(), 1);
|
assert.strictEqual(testObject.getLevel(), 1);
|
||||||
|
|
||||||
testObject.setLevel(2);
|
testObject.setLevel(2);
|
||||||
assert.equal(testObject.getLevel(), 2);
|
assert.strictEqual(testObject.getLevel(), 2);
|
||||||
|
|
||||||
testObject.setLevel(3);
|
testObject.setLevel(3);
|
||||||
assert.equal(testObject.getLevel(), 3);
|
assert.strictEqual(testObject.getLevel(), 3);
|
||||||
|
|
||||||
testObject.setLevel(4);
|
testObject.setLevel(4);
|
||||||
assert.equal(testObject.getLevel(), 4);
|
assert.strictEqual(testObject.getLevel(), 4);
|
||||||
|
|
||||||
testObject.setLevel(5);
|
testObject.setLevel(5);
|
||||||
assert.equal(testObject.getLevel(), 5);
|
assert.strictEqual(testObject.getLevel(), 5);
|
||||||
|
|
||||||
testObject.setLevel(6);
|
testObject.setLevel(6);
|
||||||
assert.equal(testObject.getLevel(), 6);
|
assert.strictEqual(testObject.getLevel(), 6);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Off Log', async function () {
|
test('Off Log', async function () {
|
||||||
|
@ -236,10 +225,6 @@ suite('API', function () {
|
||||||
testObject = await aTestObject(logFile);
|
testObject = await aTestObject(logFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('set async mode', function () {
|
|
||||||
spdlog.setAsyncMode(8192, 2000);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('set pattern', async function () {
|
test('set pattern', async function () {
|
||||||
testObject = await aTestObject(logFile);
|
testObject = await aTestObject(logFile);
|
||||||
|
|
||||||
|
@ -248,7 +233,7 @@ suite('API', function () {
|
||||||
testObject.info('This message should be written as is');
|
testObject.info('This message should be written as is');
|
||||||
|
|
||||||
const actual = await getLastLine();
|
const actual = await getLastLine();
|
||||||
assert.equal(actual, 'This message should be written as is');
|
assert.strictEqual(actual, 'This message should be written as is');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('clear formatters', async function () {
|
test('clear formatters', async function () {
|
||||||
|
@ -263,13 +248,21 @@ suite('API', function () {
|
||||||
testObject.info('as is');
|
testObject.info('as is');
|
||||||
|
|
||||||
const actuals = await getAllLines();
|
const actuals = await getAllLines();
|
||||||
assert.equal(actuals[actuals.length - 1], 'Cleared Formatters: This message should be written as is');
|
assert.strictEqual(actuals[actuals.length - 1], 'Cleared Formatters: This message should be written as is');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('create log file with special characters in file name', function () {
|
test('create log file with special characters in file name', function () {
|
||||||
let file = path.join(__dirname, 'abcdø', 'test.log');
|
let file = path.join(__dirname, 'abcdø', 'test.log');
|
||||||
filesToDelete.push(file);
|
filesToDelete.push(file);
|
||||||
testObject = new spdlog.RotatingLogger('test', file, 1048576 * 5, 2);
|
testObject = new spdlog.Logger('rotating', 'test', file, 1048576 * 5, 2);
|
||||||
|
assert.ok(testObject);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('create log file with special characters in file name await', async function () {
|
||||||
|
let file = path.join(__dirname, 'abcdø', 'test.log');
|
||||||
|
filesToDelete.push(file);
|
||||||
|
testObject = await spdlog.createRotatingLogger('test', file, 1048576 * 5, 2);
|
||||||
|
assert.ok(testObject);
|
||||||
});
|
});
|
||||||
|
|
||||||
async function getLastLine() {
|
async function getLastLine() {
|
||||||
|
@ -278,7 +271,7 @@ suite('API', function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function aTestObject(logfile) {
|
async function aTestObject(logfile) {
|
||||||
const logger = await spdlog.createRotatingLoggerAsync('test', logfile, 1048576 * 5, 2);
|
const logger = await spdlog.createAsyncRotatingLogger('test', logfile, 1048576 * 5, 2);
|
||||||
logger.setPattern('%+');
|
logger.setPattern('%+');
|
||||||
return logger;
|
return logger;
|
||||||
}
|
}
|
||||||
|
@ -289,5 +282,4 @@ suite('API', function () {
|
||||||
testObject = await aTestObject(logFile);
|
testObject = await aTestObject(logFile);
|
||||||
return content.split(EOL);
|
return content.split(EOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
Загрузка…
Ссылка в новой задаче