mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-19 23:00:13 +00:00
UBERF-5795: Improve logging capabilities (#4813)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
9dab305008
commit
053496c7c2
@ -23,25 +23,35 @@ export class MeasureMetricsContext implements MeasureContext {
|
|||||||
this.name = name
|
this.name = name
|
||||||
this.params = params
|
this.params = params
|
||||||
this.metrics = metrics
|
this.metrics = metrics
|
||||||
this.done = measure(metrics, params, fullParams)
|
this.done = measure(metrics, params, fullParams, (spend) => {
|
||||||
|
this.logger.logOperation(this.name, spend, { ...params, ...fullParams })
|
||||||
|
})
|
||||||
|
|
||||||
this.logger = logger ?? {
|
this.logger = logger ?? {
|
||||||
info: (msg, args) => {
|
info: (msg, args) => {
|
||||||
console.info(msg, ...args)
|
console.info(msg, ...Object.entries(args ?? {}).map((it) => `${it[0]}=${JSON.stringify(it[1])}`))
|
||||||
},
|
},
|
||||||
error: (msg, args) => {
|
error: (msg, args) => {
|
||||||
console.error(msg, ...args)
|
console.error(msg, ...Object.entries(args ?? {}).map((it) => `${it[0]}=${JSON.stringify(it[1])}`))
|
||||||
}
|
},
|
||||||
|
close: async () => {},
|
||||||
|
logOperation: (operation, time, params) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
measure (name: string, value: number): void {
|
measure (name: string, value: number): void {
|
||||||
const c = new MeasureMetricsContext('#' + name, {}, {}, childMetrics(this.metrics, ['#' + name]))
|
const c = new MeasureMetricsContext('#' + name, {}, {}, childMetrics(this.metrics, ['#' + name]), this.logger)
|
||||||
c.done(value)
|
c.done(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
newChild (name: string, params: ParamsType, fullParams?: FullParamsType, logger?: MeasureLogger): MeasureContext {
|
newChild (name: string, params: ParamsType, fullParams?: FullParamsType, logger?: MeasureLogger): MeasureContext {
|
||||||
return new MeasureMetricsContext(name, params, fullParams ?? {}, childMetrics(this.metrics, [name]), logger)
|
return new MeasureMetricsContext(
|
||||||
|
name,
|
||||||
|
params,
|
||||||
|
fullParams ?? {},
|
||||||
|
childMetrics(this.metrics, [name]),
|
||||||
|
logger ?? this.logger
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async with<T>(
|
async with<T>(
|
||||||
@ -50,7 +60,7 @@ export class MeasureMetricsContext implements MeasureContext {
|
|||||||
op: (ctx: MeasureContext) => T | Promise<T>,
|
op: (ctx: MeasureContext) => T | Promise<T>,
|
||||||
fullParams?: ParamsType
|
fullParams?: ParamsType
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
const c = this.newChild(name, params, fullParams)
|
const c = this.newChild(name, params, fullParams, this.logger)
|
||||||
try {
|
try {
|
||||||
let value = op(c)
|
let value = op(c)
|
||||||
if (value instanceof Promise) {
|
if (value instanceof Promise) {
|
||||||
@ -64,12 +74,24 @@ export class MeasureMetricsContext implements MeasureContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async error (message: string, ...args: any[]): Promise<void> {
|
async withLog<T>(
|
||||||
this.logger.error(message, args)
|
name: string,
|
||||||
|
params: ParamsType,
|
||||||
|
op: (ctx: MeasureContext) => T | Promise<T>,
|
||||||
|
fullParams?: ParamsType
|
||||||
|
): Promise<T> {
|
||||||
|
const st = Date.now()
|
||||||
|
const r = await this.with(name, params, op, fullParams)
|
||||||
|
this.logger.logOperation(name, Date.now() - st, { ...params, ...fullParams })
|
||||||
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
async info (message: string, ...args: any[]): Promise<void> {
|
async error (message: string, args?: Record<string, any>): Promise<void> {
|
||||||
this.logger.info(message, args)
|
this.logger.error(message, { ...this.params, ...args })
|
||||||
|
}
|
||||||
|
|
||||||
|
async info (message: string, args?: Record<string, any>): Promise<void> {
|
||||||
|
this.logger.info(message, { ...this.params, ...args })
|
||||||
}
|
}
|
||||||
|
|
||||||
end (): void {
|
end (): void {
|
||||||
|
@ -45,7 +45,12 @@ function getUpdatedTopResult (
|
|||||||
* Measure with tree expansion. Operation counter will be added only to leaf's.
|
* Measure with tree expansion. Operation counter will be added only to leaf's.
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export function measure (metrics: Metrics, params: ParamsType, fullParams: FullParamsType = {}): () => void {
|
export function measure (
|
||||||
|
metrics: Metrics,
|
||||||
|
params: ParamsType,
|
||||||
|
fullParams: FullParamsType = {},
|
||||||
|
endOp?: (spend: number) => void
|
||||||
|
): () => void {
|
||||||
const st = Date.now()
|
const st = Date.now()
|
||||||
return (value?: number) => {
|
return (value?: number) => {
|
||||||
const ed = Date.now()
|
const ed = Date.now()
|
||||||
@ -75,6 +80,7 @@ export function measure (metrics: Metrics, params: ParamsType, fullParams: FullP
|
|||||||
metrics.operations++
|
metrics.operations++
|
||||||
|
|
||||||
metrics.topResult = getUpdatedTopResult(metrics.topResult, ed - st, fullParams)
|
metrics.topResult = getUpdatedTopResult(metrics.topResult, ed - st, fullParams)
|
||||||
|
endOp?.(ed - st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,8 +37,14 @@ export interface Metrics extends MetricsData {
|
|||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export interface MeasureLogger {
|
export interface MeasureLogger {
|
||||||
info: (message: string, ...args: any[]) => void
|
info: (message: string, obj?: Record<string, any>) => void
|
||||||
error: (message: string, ...args: any[]) => void
|
error: (message: string, obj?: Record<string, any>) => void
|
||||||
|
|
||||||
|
logOperation: (operation: string, time: number, params: ParamsType) => void
|
||||||
|
|
||||||
|
childLogger?: (name: string, params: Record<string, any>) => MeasureLogger
|
||||||
|
|
||||||
|
close: () => Promise<void>
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
@ -54,13 +60,20 @@ export interface MeasureContext {
|
|||||||
fullParams?: FullParamsType
|
fullParams?: FullParamsType
|
||||||
) => Promise<T>
|
) => Promise<T>
|
||||||
|
|
||||||
|
withLog: <T>(
|
||||||
|
name: string,
|
||||||
|
params: ParamsType,
|
||||||
|
op: (ctx: MeasureContext) => T | Promise<T>,
|
||||||
|
fullParams?: FullParamsType
|
||||||
|
) => Promise<T>
|
||||||
|
|
||||||
logger: MeasureLogger
|
logger: MeasureLogger
|
||||||
|
|
||||||
measure: (name: string, value: number) => void
|
measure: (name: string, value: number) => void
|
||||||
|
|
||||||
// Capture error
|
// Capture error
|
||||||
error: (message: string, ...args: any[]) => Promise<void>
|
error: (message: string, obj?: Record<string, any>) => Promise<void>
|
||||||
info: (message: string, ...args: any[]) => Promise<void>
|
info: (message: string, obj?: Record<string, any>) => Promise<void>
|
||||||
|
|
||||||
// Mark current context as complete
|
// Mark current context as complete
|
||||||
// If no value is passed, time difference will be used.
|
// If no value is passed, time difference will be used.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { MeasureContext, MeasureLogger, ParamType } from '@hcengineering/core'
|
import { MeasureContext, MeasureLogger, ParamType, ParamsType } from '@hcengineering/core'
|
||||||
import apm, { Agent, Span, Transaction } from 'elastic-apm-node'
|
import apm, { Agent, Span, Transaction } from 'elastic-apm-node'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,11 +37,13 @@ export class APMMeasureContext implements MeasureContext {
|
|||||||
this.parent = parent
|
this.parent = parent
|
||||||
this.logger = {
|
this.logger = {
|
||||||
info: (msg, args) => {
|
info: (msg, args) => {
|
||||||
agent.logger.info(msg, args)
|
agent.logger.info({ message: msg, ...args })
|
||||||
},
|
},
|
||||||
error: (msg, args) => {
|
error: (msg, args) => {
|
||||||
agent.logger.error(msg, args)
|
agent.logger.error({ message: msg, ...args })
|
||||||
}
|
},
|
||||||
|
logOperation (operation, time, params) {},
|
||||||
|
close: async () => {}
|
||||||
}
|
}
|
||||||
if (!(noTransaction ?? false)) {
|
if (!(noTransaction ?? false)) {
|
||||||
if (this.parent === undefined) {
|
if (this.parent === undefined) {
|
||||||
@ -63,8 +65,9 @@ export class APMMeasureContext implements MeasureContext {
|
|||||||
|
|
||||||
async with<T>(
|
async with<T>(
|
||||||
name: string,
|
name: string,
|
||||||
params: Record<string, ParamType>,
|
params: ParamsType,
|
||||||
op: (ctx: MeasureContext) => T | Promise<T>
|
op: (ctx: MeasureContext) => T | Promise<T>,
|
||||||
|
fullParams?: ParamsType
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
const c = this.newChild(name, params)
|
const c = this.newChild(name, params)
|
||||||
try {
|
try {
|
||||||
@ -80,6 +83,18 @@ export class APMMeasureContext implements MeasureContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async withLog<T>(
|
||||||
|
name: string,
|
||||||
|
params: ParamsType,
|
||||||
|
op: (ctx: MeasureContext) => T | Promise<T>,
|
||||||
|
fullParams?: ParamsType
|
||||||
|
): Promise<T> {
|
||||||
|
const st = Date.now()
|
||||||
|
const r = await this.with(name, params, op, fullParams)
|
||||||
|
this.logger.logOperation(name, Date.now() - st, { ...params, ...fullParams })
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
async error (message: string, ...args: any[]): Promise<void> {
|
async error (message: string, ...args: any[]): Promise<void> {
|
||||||
this.logger.error(message, args)
|
this.logger.error(message, args)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user