202 lines
6.3 KiB
TypeScript
202 lines
6.3 KiB
TypeScript
|
|
import { MANAGER } from './manager';
|
|
import { ValueError } from './helper/error';
|
|
import { STYLES, Formatter } from './formatter';
|
|
import { StreamHandler, FileHandler, Handler } from './handler';
|
|
import { LogLevel } from './log-level';
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Configuration classes and functions
|
|
//---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* options for basic configuration of logging module
|
|
*/
|
|
export interface BasicConfigOptions {
|
|
/*
|
|
* Specifies that a FileHandler be created, using the specified filename,
|
|
* rather than a StreamHandler.
|
|
*/
|
|
filename?: string;
|
|
|
|
/**
|
|
* Specifies the mode to open the file, if filename is specified (if
|
|
* filemode is unspecified, it defaults to 'a')
|
|
*/
|
|
filemode?: string;
|
|
|
|
/**
|
|
* Use the specified format string for the handler.
|
|
*/
|
|
format?: string;
|
|
|
|
/**
|
|
* Use the specified date/time format.
|
|
*
|
|
*/
|
|
datefmt?: string;
|
|
|
|
/**
|
|
* If a format string is specified, use this to specify the type of format
|
|
* string (possible values '%', '{', '$', for %-formatting,
|
|
* :meth:`str.format` and :class:`string.Template`- defaults to '%').
|
|
*
|
|
* TODO: switch to enum
|
|
*/
|
|
style?: string;
|
|
|
|
/**
|
|
* Set the root logger level to the specified level.
|
|
*/
|
|
level?: LogLevel;
|
|
|
|
/**
|
|
* Use the specified stream to initialize the StreamHandler. Note that this
|
|
* argument is incompatible with 'filename' - if both are present, 'stream'
|
|
* is ignored.
|
|
*
|
|
* TODO:
|
|
*/
|
|
stream?: any;
|
|
|
|
/**
|
|
* If specified, this should be an iterable of already created handlers,
|
|
* which will be added to the root logger. Any handler in the list which
|
|
* does not have a formatter assigned will be assigned the formatter created
|
|
* in this function.
|
|
*/
|
|
handlers?: Handler[];
|
|
|
|
/**
|
|
* If this keyword is specified as true, any existing handlers attached to
|
|
* the root logger are removed and closed, before carrying out the
|
|
* configuration as specified by the other arguments.
|
|
*/
|
|
force?: boolean;
|
|
|
|
/**
|
|
* If specified together with a filename, this encoding is passed to the
|
|
* created FileHandler, causing it to be used when the file is opened.
|
|
*/
|
|
encoding?: string;
|
|
|
|
/**
|
|
* If specified together with a filename, this value is
|
|
* passed to the created FileHandler, causing it to be used
|
|
* when the file is opened in text mode. If not specified,
|
|
* the default value is `backslashreplace`.
|
|
*/
|
|
errors?: string|null;
|
|
}
|
|
|
|
/**
|
|
* Do basic configuration for the logging system.
|
|
*
|
|
* This function does nothing if the root logger already has handlers
|
|
* configured, unless the keyword argument *force* is set to ``True``.
|
|
* It is a convenience method intended for use by simple scripts
|
|
* to do one-shot configuration of the logging package.
|
|
*
|
|
* The default behaviour is to create a StreamHandler which writes to
|
|
* sys.stderr, set a formatter using the BASIC_FORMAT format string, and
|
|
* add the handler to the root logger.
|
|
*
|
|
* A number of optional keyword arguments may be specified, which can alter
|
|
* the default behaviour.
|
|
*
|
|
* Note that you could specify a stream created using open(filename, mode)
|
|
* rather than passing the filename and mode in. However, it should be
|
|
* remembered that StreamHandler does not close its stream (since it may be
|
|
* using sys.stdout or sys.stderr), whereas FileHandler closes its stream
|
|
* when the handler is closed.
|
|
*
|
|
* TODO: refactor logic, there apparently is some redundancy in the original
|
|
* code
|
|
*/
|
|
export function basicConfig(options: BasicConfigOptions) {
|
|
const force = options.force ?? false;
|
|
var encoding = options.encoding ?? undefined;
|
|
var errors: string|undefined = options.errors ?? 'backslashreplace';
|
|
var handlers = options.handlers ?? [];
|
|
const filename = options.filename ?? null;
|
|
const stream = options.stream ?? null;
|
|
const filemode = options.filemode ?? 'a';
|
|
const dateformat = options.filemode ?? null;
|
|
const style = options.filemode ?? '%';
|
|
const level = options.level ?? null;
|
|
|
|
if (!Object.keys(STYLES).includes(style)) {
|
|
throw new ValueError(
|
|
`style must be one of: ${Object.keys(STYLES).join(', ')}`
|
|
);
|
|
}
|
|
|
|
if (force) {
|
|
for (var i = 0; i < MANAGER.root.handlers.length; i += 1) {
|
|
let h: Handler = MANAGER.root.handlers[i];
|
|
MANAGER.root.removeHandler(h);
|
|
h.close();
|
|
}
|
|
}
|
|
|
|
if (handlers.length == 0) {
|
|
if (handlers === null && stream && filename) {
|
|
throw new ValueError(
|
|
"'stream' and 'filename' should not be specified together"
|
|
);
|
|
}
|
|
|
|
else if (stream || filename) {
|
|
throw new ValueError(
|
|
"'stream' or 'filename' should not be specified together" +
|
|
"with 'handlers'"
|
|
);
|
|
}
|
|
|
|
if (handlers === null) {
|
|
var h: Handler;
|
|
|
|
if (filename) {
|
|
if (filemode.match('b')) { errors = undefined }
|
|
else { encoding = 'utf-8' }
|
|
|
|
h = new FileHandler({
|
|
filename: filename,
|
|
filemode: filemode,
|
|
'encoding': encoding,
|
|
errors: errors
|
|
});
|
|
}
|
|
|
|
else { h = new StreamHandler(stream) }
|
|
|
|
handlers = [h];
|
|
}
|
|
|
|
for (var i = 0; i < handlers.length; i += 1) {
|
|
let h = handlers[i];
|
|
|
|
if (h.formatter === null) {
|
|
h.formatter = new Formatter({
|
|
fmt: options.format ?? STYLES[style][1],
|
|
datefmt: dateformat,
|
|
style: style
|
|
});
|
|
}
|
|
|
|
MANAGER.root.addHandler(h);
|
|
}
|
|
|
|
if (level !== null) { MANAGER.root.setLevel(level) }
|
|
|
|
if (options) {
|
|
// runtime interface guard, please let me stay. 🥺
|
|
// the interface does not allow for additional members, but the
|
|
// runtime environment has no concept of interfaces. We can stick to
|
|
// the original implementation
|
|
const keys = Object.keys(options).join(', ');
|
|
|
|
throw new ValueError(`Unrecognised argument(s): ${keys}`);
|
|
}
|
|
}
|
|
}
|