Add storage logger
This commit is contained in:
		| @@ -1,14 +1,15 @@ | ||||
| import { Scheduler } from './Scheduler'; | ||||
| import { TaskQueue } from './Queue/TaskQueue'; | ||||
| import { ConsoleLogger } from './Logger'; | ||||
| import { AggregateLogger, ConsoleLogger, LogLevel, StorageLogger } from './Logger'; | ||||
| import { ActionQueue } from './Queue/ActionQueue'; | ||||
| import { Executor } from './Executor'; | ||||
| import { ControlPanel } from './ControlPanel'; | ||||
| import { DataStorageTaskProvider } from './Queue/DataStorageTaskProvider'; | ||||
| import { Statistics } from './Statistics'; | ||||
| import { StatisticsStorage } from './Storage/StatisticsStorage'; | ||||
| import { VillageRepository, VillageRepositoryInterface } from './VillageRepository'; | ||||
| import { VillageRepository } from './VillageRepository'; | ||||
| import { VillageStateRepository } from './VillageState'; | ||||
| import { LogStorage } from './Storage/LogStorage'; | ||||
|  | ||||
| export class Container { | ||||
|     private readonly version: string; | ||||
| @@ -70,7 +71,11 @@ export class Container { | ||||
|         this._executor = | ||||
|             this._executor || | ||||
|             (() => { | ||||
|                 return new Executor(this.version, this.scheduler, this.villageStateRepository, this.statistics); | ||||
|                 const logger = new AggregateLogger([ | ||||
|                     new ConsoleLogger(Executor.name), | ||||
|                     new StorageLogger(new LogStorage(), LogLevel.warning), | ||||
|                 ]); | ||||
|                 return new Executor(this.version, this.scheduler, this.villageStateRepository, this.statistics, logger); | ||||
|             })(); | ||||
|         return this._executor; | ||||
|     } | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import { markPage, sleepMicro, timestamp, waitForLoad } from './utils'; | ||||
| import { AbortTaskError, ActionError, GrabError, TryLaterError, VillageNotFound } from './Errors'; | ||||
| import { TaskQueueRenderer } from './TaskQueueRenderer'; | ||||
| import { createActionHandler } from './Action/ActionController'; | ||||
| import { ConsoleLogger, Logger } from './Logger'; | ||||
| import { Logger } from './Logger'; | ||||
| import { GrabberManager } from './Grabber/GrabberManager'; | ||||
| import { Scheduler } from './Scheduler'; | ||||
| import { Statistics } from './Statistics'; | ||||
| @@ -29,7 +29,8 @@ export class Executor { | ||||
|         version: string, | ||||
|         scheduler: Scheduler, | ||||
|         villageStateRepository: VillageStateRepository, | ||||
|         statistics: Statistics | ||||
|         statistics: Statistics, | ||||
|         logger: Logger | ||||
|     ) { | ||||
|         this.version = version; | ||||
|         this.scheduler = scheduler; | ||||
| @@ -37,7 +38,7 @@ export class Executor { | ||||
|         this.grabbers = new GrabberManager(scheduler); | ||||
|         this.statistics = statistics; | ||||
|         this.executionState = new ExecutionStorage(); | ||||
|         this.logger = new ConsoleLogger(this.constructor.name); | ||||
|         this.logger = logger; | ||||
|     } | ||||
|  | ||||
|     async run() { | ||||
|   | ||||
| @@ -1,9 +1,17 @@ | ||||
| import { timestamp } from './utils'; | ||||
|  | ||||
| export interface Logger { | ||||
|     info(...args: any[]): void; | ||||
|     warn(...args: any[]): void; | ||||
|     error(...args: any[]): void; | ||||
| } | ||||
|  | ||||
| export enum LogLevel { | ||||
|     info = 3, | ||||
|     warning = 2, | ||||
|     error = 1, | ||||
| } | ||||
|  | ||||
| export class NullLogger implements Logger { | ||||
|     info(...args: any[]): void {} | ||||
|     warn(...args: any[]): void {} | ||||
| @@ -29,3 +37,67 @@ export class ConsoleLogger implements Logger { | ||||
|         console.error(this.name + ':', ...args); | ||||
|     } | ||||
| } | ||||
|  | ||||
| export interface StorageLogRecord { | ||||
|     level: string; | ||||
|     ts: number; | ||||
|     message: string; | ||||
| } | ||||
|  | ||||
| export interface LogStorageInterface { | ||||
|     write(record: StorageLogRecord): void; | ||||
| } | ||||
|  | ||||
| export class StorageLogger implements Logger { | ||||
|     private storage: LogStorageInterface; | ||||
|     private readonly level: LogLevel; | ||||
|  | ||||
|     constructor(storage: LogStorageInterface, level: LogLevel) { | ||||
|         this.storage = storage; | ||||
|         this.level = level; | ||||
|     } | ||||
|  | ||||
|     info(...args: any[]): void { | ||||
|         if (this.level >= LogLevel.info) { | ||||
|             this.storage.write({ level: 'info', message: args.join(' '), ts: timestamp() }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     warn(...args: any[]): void { | ||||
|         if (this.level >= LogLevel.warning) { | ||||
|             this.storage.write({ level: 'warn', message: args.join(' '), ts: timestamp() }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     error(...args: any[]): void { | ||||
|         if (this.level >= LogLevel.error) { | ||||
|             this.storage.write({ level: 'error', message: args.join(' '), ts: timestamp() }); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| export class AggregateLogger implements Logger { | ||||
|     private readonly loggers: Array<Logger>; | ||||
|  | ||||
|     constructor(loggers: Array<Logger>) { | ||||
|         this.loggers = loggers; | ||||
|     } | ||||
|  | ||||
|     info(...args: any[]): void { | ||||
|         for (let lg of this.loggers) { | ||||
|             lg.info(...args); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     warn(...args: any[]): void { | ||||
|         for (let lg of this.loggers) { | ||||
|             lg.warn(...args); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     error(...args: any[]): void { | ||||
|         for (let lg of this.loggers) { | ||||
|             lg.error(...args); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										31
									
								
								src/Storage/LogStorage.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/Storage/LogStorage.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| import { DataStorage } from '../DataStorage'; | ||||
| import { ActionStatistics, StatisticsStorageInterface } from '../Statistics'; | ||||
| import { LogStorageInterface, StorageLogRecord } from '../Logger'; | ||||
|  | ||||
| const NAMESPACE = 'logs.v1'; | ||||
| const RECORD_LIST_KEY = 'records'; | ||||
|  | ||||
| const RECORD_COUNT = 200; | ||||
|  | ||||
| export class LogStorage implements LogStorageInterface { | ||||
|     private storage: DataStorage; | ||||
|     constructor() { | ||||
|         this.storage = new DataStorage(NAMESPACE); | ||||
|     } | ||||
|  | ||||
|     write(record: StorageLogRecord): void { | ||||
|         const records = this.getRecords(); | ||||
|         records.push(record); | ||||
|         this.setRecords(records.slice(-RECORD_COUNT)); | ||||
|     } | ||||
|  | ||||
|     getRecords(): Array<StorageLogRecord> { | ||||
|         return this.storage.getTypedList<StorageLogRecord>(RECORD_LIST_KEY, { | ||||
|             factory: () => ({ level: '', message: '', ts: 0 }), | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     setRecords(records: Array<StorageLogRecord>): void { | ||||
|         this.storage.set(RECORD_LIST_KEY, records); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user