-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: experimental plugins registry; logger and metrics recorder plugins
- Loading branch information
Showing
7 changed files
with
202 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/** | ||
* Log represents a single event message to record. | ||
*/ | ||
type Log = { | ||
/** | ||
* Additional contexts to include. | ||
*/ | ||
contexts?: Record<string, string>; | ||
message: string; | ||
timestamp?: Date; | ||
}; | ||
|
||
/** | ||
* Logger gathers/emits {@link Log}. | ||
*/ | ||
export interface Logger { | ||
/** | ||
* Record logs by {@link Logger}. | ||
* @param log log to record | ||
*/ | ||
log: (log: Log) => void; | ||
|
||
/** | ||
* Record error logs by {@link Logger}. | ||
* @param log error log to record | ||
*/ | ||
error: (log: Log) => void; | ||
|
||
/** | ||
* Record warn logs by {@link Logger}. | ||
* @param log warn log to record | ||
*/ | ||
warn: (log: Log) => void; | ||
} |
60 changes: 60 additions & 0 deletions
60
packages/core/src/metric-recorder/metricsRecorder.interface.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/** | ||
* Metric represents a single event datum to record. | ||
* | ||
* @example | ||
* // Example 1, metrics with same namespace: | ||
* | ||
* const metric1 = { | ||
* contexts: { | ||
* component: "Dashboard", | ||
* }, | ||
* metricName: "latency", | ||
* metricValue: 1, | ||
* }; | ||
* | ||
* const metric2 = { | ||
* contexts: { | ||
* component: "Dashboard", | ||
* }, | ||
* metricName: "latency", | ||
* metricValue: 2, | ||
* }; | ||
* | ||
* // Example 2, metrics with different namespace due to different contexts: | ||
* | ||
* const metric1 = { | ||
* contexts: { | ||
* component: "Dashboard", | ||
* }, | ||
* metricName: "latency", | ||
* metricValue: 1, | ||
* }; | ||
* | ||
* const metric2 = { | ||
* contexts: { | ||
* component: "IotResourceExplorer", | ||
* }, | ||
* metricName: "latency", | ||
* metricValue: 2, | ||
* }; | ||
*/ | ||
type Metric = { | ||
/** | ||
* Additional contexts to separate the metricName. | ||
*/ | ||
contexts?: Record<string, string>; | ||
metricName: string; | ||
metricValue: number; | ||
timestamp?: Date; | ||
}; | ||
|
||
/** | ||
* MetricsRecorder gathers/emits {@link Metric}. | ||
*/ | ||
export interface MetricsRecorder { | ||
/** | ||
* Record metric by {@link MetricsRecorder}. | ||
* @param metric metric to record | ||
*/ | ||
record: (metric: Metric) => void; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import type { Logger } from '../logger/logger.interface'; | ||
|
||
export type LoggerSettings = { provider: () => Logger }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import type { MetricsRecorder } from '../metric-recorder/metricsRecorder.interface'; | ||
|
||
export type MetricsRecorderSettings = { provider: () => MetricsRecorder }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import type { Logger } from '../logger/logger.interface'; | ||
import type { MetricsRecorder } from '../metric-recorder/metricsRecorder.interface'; | ||
import { getLogger, getMetricsRecorder, registerLogger, registerMetricsRecorder } from './pluginsRegistry'; | ||
|
||
describe('Logger registry', () => { | ||
class MockLogClient implements Logger { | ||
log() {} | ||
error() {} | ||
warn() {} | ||
} | ||
|
||
test('does not provide logger by default', () => { | ||
const logger = getLogger(); | ||
|
||
expect(logger).toBeUndefined(); | ||
}); | ||
|
||
test('provides given logger', () => { | ||
const mockLogClient = new MockLogClient(); | ||
const mockProvider = jest.fn().mockReturnValue(mockLogClient); | ||
|
||
registerLogger({ | ||
provider: mockProvider, | ||
}); | ||
const logger = getLogger(); | ||
|
||
expect(logger).toBe(mockLogClient); | ||
expect(mockProvider).toBeCalled(); | ||
}); | ||
}); | ||
|
||
describe('MetricsRecorder registry', () => { | ||
class MockMetricsRecorder implements MetricsRecorder { | ||
record() {} | ||
} | ||
|
||
test('does not provide MetricsRecorder by default', () => { | ||
const metricsRecorder = getMetricsRecorder(); | ||
|
||
expect(metricsRecorder).toBeUndefined(); | ||
}); | ||
|
||
test('provides given MetricsRecorder', () => { | ||
const mockMetricsRecorder = new MockMetricsRecorder(); | ||
const mockProvider = jest.fn().mockReturnValue(mockMetricsRecorder); | ||
|
||
registerMetricsRecorder({ | ||
provider: mockProvider, | ||
}); | ||
const metricsRecorder = getMetricsRecorder(); | ||
|
||
expect(metricsRecorder).toBe(mockMetricsRecorder); | ||
expect(mockProvider).toBeCalled(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import type { LoggerSettings } from './loggerSettings'; | ||
import type { MetricsRecorderSettings } from './metricsRecorderSettings'; | ||
|
||
/** | ||
* Internal object to hold all of the plugins. | ||
* | ||
* @emarks Not exported to encapsulate the registry | ||
*/ | ||
const pluginsRegistry: { | ||
loggerSettings?: LoggerSettings; | ||
metricsRecorderSettings?: MetricsRecorderSettings; | ||
} = {}; | ||
|
||
/** | ||
* Register a Logger for logging AppKit logs. | ||
* @param param0 settings for Logger | ||
* @alpha | ||
*/ | ||
export const registerLogger = (settings: LoggerSettings) => { | ||
pluginsRegistry.loggerSettings = settings; | ||
}; | ||
|
||
/** | ||
* Return the registered Logger. | ||
* @returns the registered Logger. | ||
* @alpha | ||
*/ | ||
export const getLogger = () => pluginsRegistry.loggerSettings?.provider(); | ||
|
||
/** | ||
* Register a MetricsRecorder for recording AppKit metrics. | ||
* @param param0 settings for MetricsRecorder | ||
* @alpha | ||
*/ | ||
export const registerMetricsRecorder = (settings: MetricsRecorderSettings) => { | ||
pluginsRegistry.metricsRecorderSettings = settings; | ||
}; | ||
|
||
/** | ||
* Return the registered MetricsRecorder. | ||
* @returns the registered MetricsRecorder. | ||
* @alpha | ||
*/ | ||
export const getMetricsRecorder = () => pluginsRegistry.metricsRecorderSettings?.provider(); |