import { Client as ElasticClient } from '@elastic/elasticsearch'; import type { ILogContext, ILogPackage, ILogDestination } from '@push.rocks/smartlog-interfaces'; import { ElasticScheduler } from './els.classes.elasticscheduler.js'; import { ElasticIndex } from './els.classes.elasticindex.js'; export interface IStandardLogParams { message: string; severity: string; } export interface IElasticSearchConstructorOptions { indexPrefix: string; indexRetention: number; node: string; auth?: { username: string; password: string; }; } export class ElsSmartlogDestination { public client: ElasticClient; public elasticScheduler = new ElasticScheduler(this); public elasticIndex: ElasticIndex = new ElasticIndex(this); public indexPrefix: string; public indexRetention: number; constructor(optionsArg: IElasticSearchConstructorOptions) { this.client = new ElasticClient({ node: optionsArg.node, ...(optionsArg.auth && { auth: optionsArg.auth }), }); this.indexPrefix = `${optionsArg.indexPrefix}`; this.indexRetention = optionsArg.indexRetention; this.setupDataStream(); } private async setupDataStream() { // Define an index template await this.client.indices.putIndexTemplate({ name: `${this.indexPrefix}_template`, index_patterns: [`${this.indexPrefix}-*`], data_stream: {}, }); } public async log(logPackageArg: ILogPackage, scheduleOverwrite = false) { const now = new Date(); const indexToUse = `${this.indexPrefix}-data-stream`; // Use data stream name if (this.elasticScheduler.docsScheduled && !scheduleOverwrite) { this.elasticScheduler.scheduleDoc(logPackageArg); return; } await this.client.index( { index: indexToUse, body: { '@timestamp': new Date(logPackageArg.timestamp).toISOString(), ...logPackageArg, }, } ); } get logDestination(): ILogDestination { return { handleLog: async (smartlogPackageArg: ILogPackage) => { await this.log(smartlogPackageArg); }, }; } }