Actionhero uses the Winston logger. This allows for better, more customizable logging. With one simple log
command provided by Actionhero, you can log to files, the console, and more!
import { log } from "actionhero";
log("hello"); // will use the default, 'info' level
log("debug message", "debug"); // will not show up unless you have configured your logger in this NODE_ENV to be debug
log("OH NO", "emerg"); // will show up in all logger levels
log("the params were", "info", data.params); // you can log objects too
Note that you can set a level
which indicates which level (and those above it) you wish to log per transport.
emerg: 0, alert: 1, crit: 2, error: 3, warning: 4, notice: 5, info: 6, debug: 7
.config.logger.levels
and config.logger.colors
. See Winston's documentation for more informationFor example, if you set the logger's level to "notice", you would also see "crit" messages, but not "debug" messages.
To invoke the logger from your code, use: log(message, severity, metadata)
.
You can access the loggers you build up directly, getting the Winston Logger objects from import { loggers } from "actionhero"
once your server has started.
import * as winston from "winston";
/*
The loggers defined here will eventually be available via `import { loggers } from "actionhero"`
learn more about winston v3 loggers @
- https://github.com/winstonjs/winston
- https://github.com/winstonjs/winston/blob/master/docs/transports.md
*/
type ActionheroConfigLoggerBuilderArray = Array<
(config: any) => winston.Logger
>;
export const DEFAULT = {
logger: (config) => {
const loggers: ActionheroConfigLoggerBuilderArray = [];
loggers.push(buildConsoleLogger());
config.general.paths.log.forEach((p) => {
loggers.push(buildFileLogger(p));
});
return {
loggers,
maxLogStringLength: 100, // the maximum length of param to log (we will truncate)
};
},
};
export const test = {
logger: (config) => {
const loggers: ActionheroConfigLoggerBuilderArray = [];
loggers.push(buildConsoleLogger("crit"));
config.general.paths.log.forEach((p) => {
loggers.push(buildFileLogger(p, "debug", 1));
});
return { loggers };
},
};
// helpers for building the winston loggers
function buildConsoleLogger(level = "info") {
return function (config) {
return winston.createLogger({
format: winston.format.combine(
winston.format.timestamp(),
winston.format.colorize(),
winston.format.printf((info) => {
return `${info.timestamp} - ${info.level}: ${
info.message
} ${stringifyExtraMessagePropertiesForConsole(info)}`;
})
),
level,
levels: winston.config.syslog.levels,
transports: [new winston.transports.Console()],
});
};
}
function stringifyExtraMessagePropertiesForConsole(info) {
const skippedProperties = ["message", "timestamp", "level"];
let response = "";
for (const key in info) {
const value = info[key];
if (skippedProperties.includes(key)) {
continue;
}
if (value === undefined || value === null || value === "") {
continue;
}
response += `${key}=${value} `;
}
return response;
}
function buildFileLogger(path, level = "info", maxFiles = undefined) {
return function (config) {
const filename = `${path}/${config.process.id}-${config.process.env}.log`;
return winston.createLogger({
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
level,
levels: winston.config.syslog.levels,
transports: [
new winston.transports.File({
filename,
maxFiles,
}),
],
});
};
}
In your config/logger.js
, you can customize which transports
you would like the logger to use. If none are provided, a default logger which only will print to stdout will be used. See winston's documentation for all the logger types, but know that they include console, file, s3, Riak, and more.
You can set a transport directly, IE new (winston.transports.Console)()
or in a function which will be passed the api
object like the examples above. The benefit of using the function invocation is you will have access to other methods and configuration options (like the title of the process).
The Actionhero server is open source, under the Apache-2 license
Actionhero runs on Linux, OS X, and Windows
You always have access to the Actionhero team via Slack and Github
We provide support for corporate & nonprofit customers starting at a flat rate of $150/hr. Our services include:
We have packages appropriate for all company sizes. Contact us to learn more.
We provide support for corporate & nonprofit customers starting at a flat rate of $150/hr. Our services include:
We have packages appropriate for all company sizes. Contact us to learn more.
For larger customers in need of a support contract, we offer an enterprise plan including everything in the Premium plan plus: