@larablox/monolog 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/Monolog/Attribute/AsMonologProcessor.d.ts +30 -0
- package/out/Monolog/Attribute/AsMonologProcessor.luau +59 -0
- package/out/Monolog/Attribute/WithMonologChannel.d.ts +18 -0
- package/out/Monolog/Attribute/WithMonologChannel.luau +33 -0
- package/out/Monolog/Formatter/FormatterInterface.d.ts +8 -0
- package/out/Monolog/Formatter/FormatterInterface.luau +3 -0
- package/out/Monolog/Formatter/HtmlFormatter.d.ts +23 -0
- package/out/Monolog/Formatter/HtmlFormatter.luau +128 -0
- package/out/Monolog/Formatter/JsonFormatter.d.ts +34 -0
- package/out/Monolog/Formatter/JsonFormatter.luau +114 -0
- package/out/Monolog/Formatter/LineFormatter.d.ts +52 -0
- package/out/Monolog/Formatter/LineFormatter.luau +228 -0
- package/out/Monolog/Formatter/NormalizerFormatter.d.ts +87 -0
- package/out/Monolog/Formatter/NormalizerFormatter.luau +214 -0
- package/out/Monolog/Formatter/ScalarFormatter.d.ts +19 -0
- package/out/Monolog/Formatter/ScalarFormatter.luau +53 -0
- package/out/Monolog/Handler/AbstractHandler.d.ts +22 -0
- package/out/Monolog/Handler/AbstractHandler.luau +50 -0
- package/out/Monolog/Handler/AbstractProcessingHandler.d.ts +30 -0
- package/out/Monolog/Handler/AbstractProcessingHandler.luau +79 -0
- package/out/Monolog/Handler/Handler.d.ts +15 -0
- package/out/Monolog/Handler/Handler.luau +25 -0
- package/out/Monolog/Handler/HandlerInterface.d.ts +12 -0
- package/out/Monolog/Handler/HandlerInterface.luau +3 -0
- package/out/Monolog/Handler/NullHandler.d.ts +10 -0
- package/out/Monolog/Handler/NullHandler.luau +36 -0
- package/out/Monolog/Handler/RobloxConsoleHandler.d.ts +55 -0
- package/out/Monolog/Handler/RobloxConsoleHandler.luau +141 -0
- package/out/Monolog/Handler/TestHandler.d.ts +90 -0
- package/out/Monolog/Handler/TestHandler.luau +288 -0
- package/out/Monolog/Level.d.ts +38 -0
- package/out/Monolog/Level.luau +119 -0
- package/out/Monolog/LogRecord.d.ts +43 -0
- package/out/Monolog/LogRecord.luau +77 -0
- package/out/Monolog/Logger.d.ts +93 -0
- package/out/Monolog/Logger.luau +248 -0
- package/out/Monolog/LoggerInterface.d.ts +33 -0
- package/out/Monolog/LoggerInterface.luau +15 -0
- package/out/Monolog/Processor/ClosureContextProcessor.d.ts +13 -0
- package/out/Monolog/Processor/ClosureContextProcessor.luau +76 -0
- package/out/Monolog/Processor/IntrospectionProcessor.d.ts +33 -0
- package/out/Monolog/Processor/IntrospectionProcessor.luau +69 -0
- package/out/Monolog/Processor/MemoryPeakUsageProcessor.d.ts +17 -0
- package/out/Monolog/Processor/MemoryPeakUsageProcessor.luau +49 -0
- package/out/Monolog/Processor/MemoryProcessor.d.ts +20 -0
- package/out/Monolog/Processor/MemoryProcessor.luau +41 -0
- package/out/Monolog/Processor/MemoryUsageProcessor.d.ts +12 -0
- package/out/Monolog/Processor/MemoryUsageProcessor.luau +38 -0
- package/out/Monolog/Processor/ProcessIdProcessor.d.ts +13 -0
- package/out/Monolog/Processor/ProcessIdProcessor.luau +33 -0
- package/out/Monolog/Processor/ProcessorInterface.d.ts +13 -0
- package/out/Monolog/Processor/ProcessorInterface.luau +20 -0
- package/out/Monolog/Processor/PsrLogMessageProcessor.d.ts +12 -0
- package/out/Monolog/Processor/PsrLogMessageProcessor.luau +62 -0
- package/out/Monolog/Processor/TagProcessor.d.ts +12 -0
- package/out/Monolog/Processor/TagProcessor.luau +46 -0
- package/out/Monolog/Processor/UidProcessor.d.ts +18 -0
- package/out/Monolog/Processor/UidProcessor.luau +53 -0
- package/out/Monolog/Registry.d.ts +21 -0
- package/out/Monolog/Registry.luau +86 -0
- package/out/Monolog/ResettableInterface.d.ts +11 -0
- package/out/Monolog/ResettableInterface.luau +21 -0
- package/out/Monolog/Test/MonologTestCase.d.ts +26 -0
- package/out/Monolog/Test/MonologTestCase.luau +73 -0
- package/out/Monolog/Test/TestCase.d.ts +4 -0
- package/out/Monolog/Test/TestCase.luau +25 -0
- package/out/Monolog/Utils.d.ts +21 -0
- package/out/Monolog/Utils.luau +181 -0
- package/out/index.d.ts +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { AbstractHandler } from "./AbstractHandler";
|
|
2
|
+
import type { FormatterInterface } from "../Formatter/FormatterInterface";
|
|
3
|
+
import type { LogRecord } from "../LogRecord";
|
|
4
|
+
import type { Processor } from "../Processor/ProcessorInterface";
|
|
5
|
+
/**
|
|
6
|
+
* PHP: `Monolog\Handler\AbstractProcessingHandler`, which folds in
|
|
7
|
+
* `ProcessableHandlerTrait` and `FormattableHandlerTrait`.
|
|
8
|
+
*/
|
|
9
|
+
export declare abstract class AbstractProcessingHandler extends AbstractHandler {
|
|
10
|
+
protected processors: Processor[];
|
|
11
|
+
protected formatter?: FormatterInterface;
|
|
12
|
+
/** Handles a record. */
|
|
13
|
+
handle(record: LogRecord): boolean;
|
|
14
|
+
/** Writes the record down to the log of the implementing handler. */
|
|
15
|
+
protected abstract write(record: LogRecord): void;
|
|
16
|
+
/** Adds a processor in the stack. */
|
|
17
|
+
pushProcessor(processor: Processor): this;
|
|
18
|
+
/** Removes the processor on top of the stack and returns it. */
|
|
19
|
+
popProcessor(): Processor | undefined;
|
|
20
|
+
/** Processes a record. */
|
|
21
|
+
protected processRecord(record: LogRecord): LogRecord;
|
|
22
|
+
/** Sets the formatter. */
|
|
23
|
+
setFormatter(formatter: FormatterInterface): this;
|
|
24
|
+
/** Gets the formatter, building the default one on first use. */
|
|
25
|
+
getFormatter(): FormatterInterface;
|
|
26
|
+
/** Gets the default formatter. */
|
|
27
|
+
protected getDefaultFormatter(): FormatterInterface;
|
|
28
|
+
/** Resets the handler and any processors on it that support resetting. */
|
|
29
|
+
reset(): void;
|
|
30
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local AbstractHandler = TS.import(script, script.Parent, "AbstractHandler").AbstractHandler
|
|
4
|
+
local LineFormatter = TS.import(script, script.Parent.Parent, "Formatter", "LineFormatter").LineFormatter
|
|
5
|
+
local isResettable = TS.import(script, script.Parent.Parent, "ResettableInterface").isResettable
|
|
6
|
+
local runProcessor = TS.import(script, script.Parent.Parent, "Processor", "ProcessorInterface").runProcessor
|
|
7
|
+
--[[
|
|
8
|
+
*
|
|
9
|
+
* PHP: `Monolog\Handler\AbstractProcessingHandler`, which folds in
|
|
10
|
+
* `ProcessableHandlerTrait` and `FormattableHandlerTrait`.
|
|
11
|
+
|
|
12
|
+
]]
|
|
13
|
+
local AbstractProcessingHandler
|
|
14
|
+
do
|
|
15
|
+
local super = AbstractHandler
|
|
16
|
+
AbstractProcessingHandler = setmetatable({}, {
|
|
17
|
+
__tostring = function()
|
|
18
|
+
return "AbstractProcessingHandler"
|
|
19
|
+
end,
|
|
20
|
+
__index = super,
|
|
21
|
+
})
|
|
22
|
+
AbstractProcessingHandler.__index = AbstractProcessingHandler
|
|
23
|
+
function AbstractProcessingHandler:constructor(...)
|
|
24
|
+
super.constructor(self, ...)
|
|
25
|
+
self.processors = {}
|
|
26
|
+
end
|
|
27
|
+
function AbstractProcessingHandler:handle(record)
|
|
28
|
+
if not self:isHandling(record) then
|
|
29
|
+
return false
|
|
30
|
+
end
|
|
31
|
+
local processed = record
|
|
32
|
+
if not (#self.processors == 0) then
|
|
33
|
+
processed = self:processRecord(processed)
|
|
34
|
+
end
|
|
35
|
+
processed.formatted = self:getFormatter():format(processed)
|
|
36
|
+
self:write(processed)
|
|
37
|
+
return self.bubble == false
|
|
38
|
+
end
|
|
39
|
+
function AbstractProcessingHandler:pushProcessor(processor)
|
|
40
|
+
local _processors = self.processors
|
|
41
|
+
local _processor = processor
|
|
42
|
+
table.insert(_processors, 1, _processor)
|
|
43
|
+
return self
|
|
44
|
+
end
|
|
45
|
+
function AbstractProcessingHandler:popProcessor()
|
|
46
|
+
return table.remove(self.processors, 1)
|
|
47
|
+
end
|
|
48
|
+
function AbstractProcessingHandler:processRecord(record)
|
|
49
|
+
local processed = record
|
|
50
|
+
for _, processor in self.processors do
|
|
51
|
+
processed = runProcessor(processor, processed)
|
|
52
|
+
end
|
|
53
|
+
return processed
|
|
54
|
+
end
|
|
55
|
+
function AbstractProcessingHandler:setFormatter(formatter)
|
|
56
|
+
self.formatter = formatter
|
|
57
|
+
return self
|
|
58
|
+
end
|
|
59
|
+
function AbstractProcessingHandler:getFormatter()
|
|
60
|
+
if self.formatter == nil then
|
|
61
|
+
self.formatter = self:getDefaultFormatter()
|
|
62
|
+
end
|
|
63
|
+
return self.formatter
|
|
64
|
+
end
|
|
65
|
+
function AbstractProcessingHandler:getDefaultFormatter()
|
|
66
|
+
return LineFormatter.new()
|
|
67
|
+
end
|
|
68
|
+
function AbstractProcessingHandler:reset()
|
|
69
|
+
super.reset(self)
|
|
70
|
+
for _, processor in self.processors do
|
|
71
|
+
if isResettable(processor) then
|
|
72
|
+
processor:reset()
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
return {
|
|
78
|
+
AbstractProcessingHandler = AbstractProcessingHandler,
|
|
79
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { HandlerInterface } from "./HandlerInterface";
|
|
2
|
+
import type { LogRecord } from "../LogRecord";
|
|
3
|
+
/**
|
|
4
|
+
* PHP: `Monolog\Handler\Handler`.
|
|
5
|
+
*
|
|
6
|
+
* `__destruct` and `__serialize` are not ported: Luau has neither.
|
|
7
|
+
*/
|
|
8
|
+
export declare abstract class Handler implements HandlerInterface {
|
|
9
|
+
abstract isHandling(record: LogRecord): boolean;
|
|
10
|
+
abstract handle(record: LogRecord): boolean;
|
|
11
|
+
/** Handles a set of records at once. */
|
|
12
|
+
handleBatch(records: Array<LogRecord>): void;
|
|
13
|
+
/** Closes the handler. */
|
|
14
|
+
close(): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
--[[
|
|
3
|
+
*
|
|
4
|
+
* PHP: `Monolog\Handler\Handler`.
|
|
5
|
+
*
|
|
6
|
+
* `__destruct` and `__serialize` are not ported: Luau has neither.
|
|
7
|
+
|
|
8
|
+
]]
|
|
9
|
+
local Handler
|
|
10
|
+
do
|
|
11
|
+
Handler = {}
|
|
12
|
+
function Handler:constructor()
|
|
13
|
+
end
|
|
14
|
+
function Handler:handleBatch(records)
|
|
15
|
+
for _, record in records do
|
|
16
|
+
self:handle(record)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
function Handler:close()
|
|
20
|
+
--
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
return {
|
|
24
|
+
Handler = Handler,
|
|
25
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { LogRecord } from "../LogRecord";
|
|
2
|
+
/** PHP: `Monolog\Handler\HandlerInterface`. */
|
|
3
|
+
export interface HandlerInterface {
|
|
4
|
+
/** Checks whether the given record will be handled by this handler. */
|
|
5
|
+
isHandling(record: LogRecord): boolean;
|
|
6
|
+
/** Handles a record. Returning true stops the bubbling chain. */
|
|
7
|
+
handle(record: LogRecord): boolean;
|
|
8
|
+
/** Handles a set of records at once. */
|
|
9
|
+
handleBatch(records: Array<LogRecord>): void;
|
|
10
|
+
/** Closes the handler. */
|
|
11
|
+
close(): void;
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Handler } from "./Handler";
|
|
2
|
+
import { Level } from "../Level";
|
|
3
|
+
import type { LogRecord } from "../LogRecord";
|
|
4
|
+
/** PHP: `Monolog\Handler\NullHandler`. Swallows everything at or above the level. */
|
|
5
|
+
export declare class NullHandler extends Handler {
|
|
6
|
+
protected readonly level: Level;
|
|
7
|
+
constructor(level?: Level);
|
|
8
|
+
isHandling(record: LogRecord): boolean;
|
|
9
|
+
handle(record: LogRecord): boolean;
|
|
10
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local Handler = TS.import(script, script.Parent, "Handler").Handler
|
|
4
|
+
local Level = TS.import(script, script.Parent.Parent, "Level").Level
|
|
5
|
+
--* PHP: `Monolog\Handler\NullHandler`. Swallows everything at or above the level.
|
|
6
|
+
local NullHandler
|
|
7
|
+
do
|
|
8
|
+
local super = Handler
|
|
9
|
+
NullHandler = setmetatable({}, {
|
|
10
|
+
__tostring = function()
|
|
11
|
+
return "NullHandler"
|
|
12
|
+
end,
|
|
13
|
+
__index = super,
|
|
14
|
+
})
|
|
15
|
+
NullHandler.__index = NullHandler
|
|
16
|
+
function NullHandler.new(...)
|
|
17
|
+
local self = setmetatable({}, NullHandler)
|
|
18
|
+
return self:constructor(...) or self
|
|
19
|
+
end
|
|
20
|
+
function NullHandler:constructor(level)
|
|
21
|
+
if level == nil then
|
|
22
|
+
level = Level.Debug
|
|
23
|
+
end
|
|
24
|
+
super.constructor(self)
|
|
25
|
+
self.level = level
|
|
26
|
+
end
|
|
27
|
+
function NullHandler:isHandling(record)
|
|
28
|
+
return record.level >= self.level
|
|
29
|
+
end
|
|
30
|
+
function NullHandler:handle(record)
|
|
31
|
+
return record.level >= self.level
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
return {
|
|
35
|
+
NullHandler = NullHandler,
|
|
36
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { AbstractProcessingHandler } from "./AbstractProcessingHandler";
|
|
2
|
+
import { Level } from "../Level";
|
|
3
|
+
import type { FormatterInterface } from "../Formatter/FormatterInterface";
|
|
4
|
+
import type { LogRecord } from "../LogRecord";
|
|
5
|
+
/**
|
|
6
|
+
* PHP: `Monolog\Handler\PHPConsoleHandler`.
|
|
7
|
+
*
|
|
8
|
+
* Upstream streams debug/error/exception data to the (now abandoned) "PHP
|
|
9
|
+
* Console" Chrome extension via `PhpConsole\Connector`. There is no such
|
|
10
|
+
* target on Roblox, so this adapts the same handler shape -- the `options`
|
|
11
|
+
* bag, the record-kind branching in `write()`, the default formatter -- to
|
|
12
|
+
* the platform's own output console (`print`/`warn`) instead, superseding
|
|
13
|
+
* what the old, not-a-real-upstream-class `ConsoleHandler` used to do.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Reduced from upstream's `Options`: everything else there
|
|
17
|
+
* (`classesPartialsTraceIgnore`, `useOwnErrorsHandler`/`useOwnExceptionsHandler`,
|
|
18
|
+
* `sourcesBasePath`, `registerHelper`, `serverEncoding`, `headersLimit`,
|
|
19
|
+
* `password`, `enableSslOnlyMode`, `ipMasks`, `enableEvalListener`, every
|
|
20
|
+
* `dumper*` key, `detectDumpTraceAndSource`, `dataStorage`) is either specific
|
|
21
|
+
* to the PHP Console wire protocol or paired with `ErrorHandler`/`SignalHandler`,
|
|
22
|
+
* both out of scope for this port -- there is no connector object left to
|
|
23
|
+
* configure with them.
|
|
24
|
+
*/
|
|
25
|
+
export interface Options {
|
|
26
|
+
/** Whether this handler is active at all. */
|
|
27
|
+
enabled: boolean;
|
|
28
|
+
/** Context keys checked, in order, for a debug "tag" to prefix the message with. */
|
|
29
|
+
debugTagsKeysInContext: Array<string>;
|
|
30
|
+
}
|
|
31
|
+
export declare class RobloxConsoleHandler extends AbstractProcessingHandler {
|
|
32
|
+
private readonly options;
|
|
33
|
+
constructor(options?: Partial<Options>, level?: Level, bubble?: boolean);
|
|
34
|
+
/** PHP: `PHPConsoleHandler::getOptions()`. */
|
|
35
|
+
getOptions(): Options;
|
|
36
|
+
/** PHP: `PHPConsoleHandler::handle()`. */
|
|
37
|
+
handle(record: LogRecord): boolean;
|
|
38
|
+
/** PHP: `PHPConsoleHandler::write()`. */
|
|
39
|
+
protected write(record: LogRecord): void;
|
|
40
|
+
/** PHP: `PHPConsoleHandler::handleDebugRecord()`. */
|
|
41
|
+
private writeDebugRecord;
|
|
42
|
+
/** PHP: `PHPConsoleHandler::handleExceptionRecord()`. */
|
|
43
|
+
private writeExceptionRecord;
|
|
44
|
+
/** PHP: `PHPConsoleHandler::handleErrorRecord()`. */
|
|
45
|
+
private writeErrorRecord;
|
|
46
|
+
/**
|
|
47
|
+
* PHP: `PHPConsoleHandler::getRecordTags()`. Upstream also checks
|
|
48
|
+
* `$filteredContext[0]`, PHP's implicit first-array-index -- Luau/TS have
|
|
49
|
+
* no positional index on a `RecordBag`, so only the named
|
|
50
|
+
* `debugTagsKeysInContext` keys are checked.
|
|
51
|
+
*/
|
|
52
|
+
private getRecordTags;
|
|
53
|
+
/** PHP: `PHPConsoleHandler::getDefaultFormatter()`. */
|
|
54
|
+
protected getDefaultFormatter(): FormatterInterface;
|
|
55
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local AbstractProcessingHandler = TS.import(script, script.Parent, "AbstractProcessingHandler").AbstractProcessingHandler
|
|
4
|
+
local _Level = TS.import(script, script.Parent.Parent, "Level")
|
|
5
|
+
local Level = _Level.Level
|
|
6
|
+
local Levels = _Level.Levels
|
|
7
|
+
local LineFormatter = TS.import(script, script.Parent.Parent, "Formatter", "LineFormatter").LineFormatter
|
|
8
|
+
local Utils = TS.import(script, script.Parent.Parent, "Utils").Utils
|
|
9
|
+
--[[
|
|
10
|
+
*
|
|
11
|
+
* PHP: `Monolog\Handler\PHPConsoleHandler`.
|
|
12
|
+
*
|
|
13
|
+
* Upstream streams debug/error/exception data to the (now abandoned) "PHP
|
|
14
|
+
* Console" Chrome extension via `PhpConsole\Connector`. There is no such
|
|
15
|
+
* target on Roblox, so this adapts the same handler shape -- the `options`
|
|
16
|
+
* bag, the record-kind branching in `write()`, the default formatter -- to
|
|
17
|
+
* the platform's own output console (`print`/`warn`) instead, superseding
|
|
18
|
+
* what the old, not-a-real-upstream-class `ConsoleHandler` used to do.
|
|
19
|
+
|
|
20
|
+
]]
|
|
21
|
+
--[[
|
|
22
|
+
*
|
|
23
|
+
* Reduced from upstream's `Options`: everything else there
|
|
24
|
+
* (`classesPartialsTraceIgnore`, `useOwnErrorsHandler`/`useOwnExceptionsHandler`,
|
|
25
|
+
* `sourcesBasePath`, `registerHelper`, `serverEncoding`, `headersLimit`,
|
|
26
|
+
* `password`, `enableSslOnlyMode`, `ipMasks`, `enableEvalListener`, every
|
|
27
|
+
* `dumper*` key, `detectDumpTraceAndSource`, `dataStorage`) is either specific
|
|
28
|
+
* to the PHP Console wire protocol or paired with `ErrorHandler`/`SignalHandler`,
|
|
29
|
+
* both out of scope for this port -- there is no connector object left to
|
|
30
|
+
* configure with them.
|
|
31
|
+
|
|
32
|
+
]]
|
|
33
|
+
local DEFAULT_OPTIONS = {
|
|
34
|
+
enabled = true,
|
|
35
|
+
debugTagsKeysInContext = { "tag" },
|
|
36
|
+
}
|
|
37
|
+
local RobloxConsoleHandler
|
|
38
|
+
do
|
|
39
|
+
local super = AbstractProcessingHandler
|
|
40
|
+
RobloxConsoleHandler = setmetatable({}, {
|
|
41
|
+
__tostring = function()
|
|
42
|
+
return "RobloxConsoleHandler"
|
|
43
|
+
end,
|
|
44
|
+
__index = super,
|
|
45
|
+
})
|
|
46
|
+
RobloxConsoleHandler.__index = RobloxConsoleHandler
|
|
47
|
+
function RobloxConsoleHandler.new(...)
|
|
48
|
+
local self = setmetatable({}, RobloxConsoleHandler)
|
|
49
|
+
return self:constructor(...) or self
|
|
50
|
+
end
|
|
51
|
+
function RobloxConsoleHandler:constructor(options, level, bubble)
|
|
52
|
+
if options == nil then
|
|
53
|
+
options = {}
|
|
54
|
+
end
|
|
55
|
+
if level == nil then
|
|
56
|
+
level = Level.Debug
|
|
57
|
+
end
|
|
58
|
+
if bubble == nil then
|
|
59
|
+
bubble = true
|
|
60
|
+
end
|
|
61
|
+
super.constructor(self, level, bubble)
|
|
62
|
+
local _object = {}
|
|
63
|
+
local _left = "enabled"
|
|
64
|
+
local _condition = options.enabled
|
|
65
|
+
if _condition == nil then
|
|
66
|
+
_condition = DEFAULT_OPTIONS.enabled
|
|
67
|
+
end
|
|
68
|
+
_object[_left] = _condition
|
|
69
|
+
_object.debugTagsKeysInContext = options.debugTagsKeysInContext or DEFAULT_OPTIONS.debugTagsKeysInContext
|
|
70
|
+
self.options = _object
|
|
71
|
+
end
|
|
72
|
+
function RobloxConsoleHandler:getOptions()
|
|
73
|
+
return self.options
|
|
74
|
+
end
|
|
75
|
+
function RobloxConsoleHandler:handle(record)
|
|
76
|
+
if self.options.enabled then
|
|
77
|
+
return super.handle(self, record)
|
|
78
|
+
end
|
|
79
|
+
-- Upstream also requires `connector.isActiveClient()` here; there is no
|
|
80
|
+
-- connector to ask, so `enabled` is the only gate left.
|
|
81
|
+
return not self.bubble
|
|
82
|
+
end
|
|
83
|
+
function RobloxConsoleHandler:write(record)
|
|
84
|
+
if Levels:isLowerThan(record.level, Level.Notice) then
|
|
85
|
+
self:writeDebugRecord(record)
|
|
86
|
+
elseif record.context.exception ~= nil then
|
|
87
|
+
self:writeExceptionRecord(record)
|
|
88
|
+
else
|
|
89
|
+
self:writeErrorRecord(record)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
function RobloxConsoleHandler:writeDebugRecord(record)
|
|
93
|
+
local _binding = self:getRecordTags(record)
|
|
94
|
+
local tags = _binding[1]
|
|
95
|
+
local filteredContext = _binding[2]
|
|
96
|
+
local message = record.message
|
|
97
|
+
if (next(filteredContext)) ~= nil then
|
|
98
|
+
message = `{message} {Utils:jsonEncode(filteredContext)}`
|
|
99
|
+
end
|
|
100
|
+
print(`[{tags}] {message}`)
|
|
101
|
+
end
|
|
102
|
+
function RobloxConsoleHandler:writeExceptionRecord(record)
|
|
103
|
+
warn(tostring(record.context.exception))
|
|
104
|
+
end
|
|
105
|
+
function RobloxConsoleHandler:writeErrorRecord(record)
|
|
106
|
+
local context = record.context
|
|
107
|
+
local message = if context.message ~= nil then tostring(context.message) else record.message
|
|
108
|
+
if context.file == nil and context.line == nil then
|
|
109
|
+
warn(message)
|
|
110
|
+
return nil
|
|
111
|
+
end
|
|
112
|
+
local file = if context.file ~= nil then tostring(context.file) else "?"
|
|
113
|
+
local line = if context.line ~= nil then tostring(context.line) else "?"
|
|
114
|
+
warn(`{message} ({file}:{line})`)
|
|
115
|
+
end
|
|
116
|
+
function RobloxConsoleHandler:getRecordTags(record)
|
|
117
|
+
local filteredContext = {}
|
|
118
|
+
for key, value in pairs(record.context) do
|
|
119
|
+
filteredContext[key] = value
|
|
120
|
+
end
|
|
121
|
+
local tag
|
|
122
|
+
for _, key in self.options.debugTagsKeysInContext do
|
|
123
|
+
if filteredContext[key] ~= nil then
|
|
124
|
+
tag = tostring(filteredContext[key])
|
|
125
|
+
filteredContext[key] = nil
|
|
126
|
+
break
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
local _condition = tag
|
|
130
|
+
if _condition == nil then
|
|
131
|
+
_condition = Levels:toPsrLogLevel(record.level)
|
|
132
|
+
end
|
|
133
|
+
return { _condition, filteredContext }
|
|
134
|
+
end
|
|
135
|
+
function RobloxConsoleHandler:getDefaultFormatter()
|
|
136
|
+
return LineFormatter.new("%message%")
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
return {
|
|
140
|
+
RobloxConsoleHandler = RobloxConsoleHandler,
|
|
141
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { AbstractProcessingHandler } from "./AbstractProcessingHandler";
|
|
2
|
+
import { Level } from "../Level";
|
|
3
|
+
import type { LogLevel } from "../LoggerInterface";
|
|
4
|
+
import type { LogRecord, RecordBag } from "../LogRecord";
|
|
5
|
+
/** PHP: the `array{message: string, context?: mixed[]}` shape `hasRecord()` accepts. */
|
|
6
|
+
export interface RecordAssertion {
|
|
7
|
+
message: string;
|
|
8
|
+
context?: RecordBag;
|
|
9
|
+
}
|
|
10
|
+
/** PHP: the `callable(LogRecord, int): mixed $predicate` shape `hasRecordThatPasses()` accepts. */
|
|
11
|
+
export type RecordPredicate = (record: LogRecord, index: number) => boolean;
|
|
12
|
+
/**
|
|
13
|
+
* PHP: `Monolog\Handler\TestHandler`.
|
|
14
|
+
*
|
|
15
|
+
* Ships in Monolog's real (non-dev) autoload, not `autoload-dev`, because
|
|
16
|
+
* library consumers use it in their own tests -- the same reason this port
|
|
17
|
+
* carries it under `src/Monolog/Handler` rather than `tests/`, and the same
|
|
18
|
+
* justification already made for `Monolog\Test\MonologTestCase`.
|
|
19
|
+
*
|
|
20
|
+
* Upstream's per-level shorthands (`hasWarning()`, `hasWarningRecords()`,
|
|
21
|
+
* `hasWarningThatContains()`, `hasWarningThatMatches()`,
|
|
22
|
+
* `hasWarningThatPasses()`, one set per `Level` case) are dispatched through
|
|
23
|
+
* PHP's `__call` magic method: it regex-matches the requested method name
|
|
24
|
+
* apart into a level name and a generic method name, then redirects to the
|
|
25
|
+
* matching `hasRecord*()` method with the parsed `Level` appended. Luau has
|
|
26
|
+
* no dynamic method dispatch to replicate that with, so every shorthand is
|
|
27
|
+
* spelled out explicitly below instead -- one small delegating method per
|
|
28
|
+
* level per kind, same names, same behavior.
|
|
29
|
+
*
|
|
30
|
+
* `hasRecordThatMatches()`/the `*ThatMatches()` shorthands use Luau string
|
|
31
|
+
* patterns (`string.match`) rather than upstream's PCRE (`preg_match`) --
|
|
32
|
+
* there is no PCRE engine on this platform. Pattern syntax differs
|
|
33
|
+
* (`%d`/`%a`/... instead of `\d`/`\w`/...); callers passing a `regex` should
|
|
34
|
+
* pass a Lua pattern, not a PCRE one.
|
|
35
|
+
*/
|
|
36
|
+
export declare class TestHandler extends AbstractProcessingHandler {
|
|
37
|
+
protected records: LogRecord[];
|
|
38
|
+
protected recordsByLevel: Map<Level, LogRecord[]>;
|
|
39
|
+
private skipReset;
|
|
40
|
+
getRecords(): Array<LogRecord>;
|
|
41
|
+
clear(): void;
|
|
42
|
+
reset(): void;
|
|
43
|
+
setSkipReset(skipReset: boolean): void;
|
|
44
|
+
hasRecords(level: Level | LogLevel): boolean;
|
|
45
|
+
hasRecord(recordAssertions: string | RecordAssertion, level: Level): boolean;
|
|
46
|
+
hasRecordThatContains(message: string, level: Level): boolean;
|
|
47
|
+
hasRecordThatMatches(regex: string, level: Level): boolean;
|
|
48
|
+
hasRecordThatPasses(predicate: RecordPredicate, level: Level | LogLevel): boolean;
|
|
49
|
+
protected write(record: LogRecord): void;
|
|
50
|
+
hasEmergencyRecords(): boolean;
|
|
51
|
+
hasEmergency(recordAssertions: string | RecordAssertion): boolean;
|
|
52
|
+
hasEmergencyThatContains(message: string): boolean;
|
|
53
|
+
hasEmergencyThatMatches(regex: string): boolean;
|
|
54
|
+
hasEmergencyThatPasses(predicate: RecordPredicate): boolean;
|
|
55
|
+
hasAlertRecords(): boolean;
|
|
56
|
+
hasAlert(recordAssertions: string | RecordAssertion): boolean;
|
|
57
|
+
hasAlertThatContains(message: string): boolean;
|
|
58
|
+
hasAlertThatMatches(regex: string): boolean;
|
|
59
|
+
hasAlertThatPasses(predicate: RecordPredicate): boolean;
|
|
60
|
+
hasCriticalRecords(): boolean;
|
|
61
|
+
hasCritical(recordAssertions: string | RecordAssertion): boolean;
|
|
62
|
+
hasCriticalThatContains(message: string): boolean;
|
|
63
|
+
hasCriticalThatMatches(regex: string): boolean;
|
|
64
|
+
hasCriticalThatPasses(predicate: RecordPredicate): boolean;
|
|
65
|
+
hasErrorRecords(): boolean;
|
|
66
|
+
hasError(recordAssertions: string | RecordAssertion): boolean;
|
|
67
|
+
hasErrorThatContains(message: string): boolean;
|
|
68
|
+
hasErrorThatMatches(regex: string): boolean;
|
|
69
|
+
hasErrorThatPasses(predicate: RecordPredicate): boolean;
|
|
70
|
+
hasWarningRecords(): boolean;
|
|
71
|
+
hasWarning(recordAssertions: string | RecordAssertion): boolean;
|
|
72
|
+
hasWarningThatContains(message: string): boolean;
|
|
73
|
+
hasWarningThatMatches(regex: string): boolean;
|
|
74
|
+
hasWarningThatPasses(predicate: RecordPredicate): boolean;
|
|
75
|
+
hasNoticeRecords(): boolean;
|
|
76
|
+
hasNotice(recordAssertions: string | RecordAssertion): boolean;
|
|
77
|
+
hasNoticeThatContains(message: string): boolean;
|
|
78
|
+
hasNoticeThatMatches(regex: string): boolean;
|
|
79
|
+
hasNoticeThatPasses(predicate: RecordPredicate): boolean;
|
|
80
|
+
hasInfoRecords(): boolean;
|
|
81
|
+
hasInfo(recordAssertions: string | RecordAssertion): boolean;
|
|
82
|
+
hasInfoThatContains(message: string): boolean;
|
|
83
|
+
hasInfoThatMatches(regex: string): boolean;
|
|
84
|
+
hasInfoThatPasses(predicate: RecordPredicate): boolean;
|
|
85
|
+
hasDebugRecords(): boolean;
|
|
86
|
+
hasDebug(recordAssertions: string | RecordAssertion): boolean;
|
|
87
|
+
hasDebugThatContains(message: string): boolean;
|
|
88
|
+
hasDebugThatMatches(regex: string): boolean;
|
|
89
|
+
hasDebugThatPasses(predicate: RecordPredicate): boolean;
|
|
90
|
+
}
|