UNPKG

ts-logger-tools

Version:

`ts-logger-tools` 是一个基于 TypeScript 的日志工具包,旨在为 Node.js 应用程序提供强大的日志记录和管理功能。它支持多种日志类型,包括访问日志、应用日志,并且可以与 MongoDB 集成,用于日志的存储和查询。

345 lines (344 loc) 12.7 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SLSLogSyncer = void 0; // src/syncer/sls.ts // @ts-ignore const aliyun_sdk_1 = __importDefault(require("aliyun-sdk")); const sls20201230_1 = __importStar(require("@alicloud/sls20201230")), $Sls20201230 = sls20201230_1; const $OpenApi = __importStar(require("@alicloud/openapi-client")); const $Util = __importStar(require("@alicloud/tea-util")); const LogSyncer_1 = require("../base/LogSyncer"); const LogStoreIndex_1 = __importDefault(require("../base/LogStoreIndex")); class SLSLogSyncer extends LogSyncer_1.LogSyncer { async syncAccessLog(log) { await this.PutLogs(this.accessLog, log); } async syncLoginLog(log) { await this.PutLogs(this.applicationLog, log); } async syncApplicationLog(log) { await this.PutLogs(this.applicationLog, log); } async syncSecurityLog(log) { await this.PutLogs(this.applicationLog, log); } async syncTraceLog(log) { await this.PutLogs(this.applicationLog, log); } async queryAccessLogs(filter, skip, limit, sort) { const query = this.buildQuery(filter, sort); const results = await this.GetLogs(this.accessLog, query); return results; } async queryApplicationLogs(filter, skip, limit, sort) { const query = this.buildQuery(filter, sort); const results = await this.GetLogs(this.applicationLog, query); return results; } async countAccessLogs(filter) { let query = ""; if (typeof filter === "object") { for (let key in filter) { query += ` and ${key} = "${filter[key]}"`; } } const results = await this.GetLogs(this.accessLog, `* ${query} | select count(*) as num`); return results?.body || 0; } async countApplicationLogs(filter) { let query = ""; if (typeof filter === "object") { for (let key in filter) { query += ` and ${key} = "${filter[key]}"`; } } const results = await this.GetLogs(this.applicationLog, `* ${query} | select count(*) as num`); return results?.body || 0; } async countDistinctUsersAccessLogs(filter) { let query = ""; if (typeof filter === "object") { for (let key in filter) { query += ` and ${key} = "${filter[key]}"`; } } const results = await this.GetLogs(this.accessLog, `* ${query} | select count(distinct userId) as num`); return results?.body || 0; } async countDistinctUsersApplicationLogs(filter) { let query = ""; if (typeof filter === "object") { for (let key in filter) { query += ` and ${key} = "${filter[key]}"`; } } const results = await this.GetLogs(this.applicationLog, `* ${query} | select count(distinct userId) as num`); return results?.body || 0; } async queryLogsByTraceId(traceId) { const ac = await this.GetLogs(this.accessLog, `* and traceId = ${traceId} `); const ap = await this.GetLogs(this.applicationLog, `* and traceId = ${traceId} `); return [...ac.body, ...ap.body]; } constructor(config) { super(); this.project = config.project; this.accessLog = config.accessLog || "accessLogs"; this.applicationLog = config.applicationLog || "applicationLogs"; this.client = SLSLogSyncer.createClient(config); this.client2 = new aliyun_sdk_1.default.SLS({ accessKeyId: config.accessKeyId, secretAccessKey: config.accessKeySecret, endpoint: `https://${config.endpoint}`, apiVersion: "2015-06-01", }); this.initProject(); } static createClient(data) { let config = new $OpenApi.Config({ accessKeyId: data.accessKeyId, accessKeySecret: data.accessKeySecret, }); config.endpoint = data.endpoint; return new sls20201230_1.default(config); } getClient() { return this.client; } async initProject() { let project = await this.GetProject(); if (!project) project = await this.CreateProject(); if (project) { let accessLogs = await this.GetLogStore(this.accessLog); if (!accessLogs) accessLogs = await this.CreateLogStore(this.accessLog); let applicationLogs = await this.GetLogStore(this.applicationLog); if (!applicationLogs) applicationLogs = await this.CreateLogStore(this.applicationLog); if (!accessLogs || !applicationLogs) throw new Error("AccessLogs and applicationLogs must not found"); await this.CreateIndex(this.accessLog, LogStoreIndex_1.default.accessLogs); await this.CreateIndex(this.applicationLog, LogStoreIndex_1.default.applicationLogs); console.log("Initializing project"); } else { throw new Error("Project must be specified"); } } async GetProject() { let runtime = new $Util.RuntimeOptions({}); let headers = {}; try { // 复制代码运行请自行打印 API 的返回值 return await this.client.getProjectWithOptions(this.project, headers, runtime); } catch (error) { console.log(error); console.log(error.message); console.log(error?.data["Recommend"]); return null; } } async CreateProject() { let createProjectRequest = new $Sls20201230.CreateProjectRequest({ description: "ts-logger-tools系统自动创建的SLS日志项目", projectName: this.project, }); let runtime = new $Util.RuntimeOptions({}); let headers = {}; try { return await this.client.createProjectWithOptions(createProjectRequest, headers, runtime); } catch (error) { console.log(error.message); console.log(error.data["Recommend"]); return null; } } async GetLogStore(log) { let runtime = new $Util.RuntimeOptions({}); let headers = {}; try { return await this.client.getLogStoreWithOptions(this.project, log, headers, runtime); } catch (error) { console.log(error.message); console.log(error.data["Recommend"]); return null; } } async CreateLogStore(log) { let createLogStoreRequest = new $Sls20201230.CreateLogStoreRequest({ logstoreName: log, shardCount: 2, ttl: 3650, }); let runtime = new $Util.RuntimeOptions({}); let headers = {}; try { return await this.client.createLogStoreWithOptions(this.project, createLogStoreRequest, headers, runtime); } catch (error) { console.log(error.message); console.log(error.data["Recommend"]); return null; } } async CreateIndex(log, index) { const param = { projectName: this.project, logstoreName: log, indexDetail: { line: index.line, keys: index.keys, }, }; this.client2.createIndex(param, function (err, data) { if (err) { console.log(err?.message); } else { console.log("为logStore创建索引成功", data); } }); } async PutLogs(log, logs) { const dictList = []; for (const i in logs) { const dict = { key: i, value: "", }; try { if (typeof logs[i] === "string") { dict.value = logs[i]; } if (["number", "boolean"].includes(typeof logs[i])) { dict.value = logs[i].toString(); } if (typeof logs[i] === "object") { dict.value = JSON.stringify(logs[i]); } dictList.push(dict); } catch (e) { console.log(logs[i]); // console.error(e) } } const param = { projectName: this.project, logStoreName: log, logGroup: { // 必选,写入的日志数据。 logs: [ { time: Math.floor(new Date().getTime() / 1000), contents: dictList, }, ], topic: log, source: "logistics.sk-yuan.com", }, }; this.client2.putLogs(param, function (err, data) { if (err) { console.error("error:", err); } else { // console.log('写入日志成功', data) } }); } async GetLogs(log, query, timeInterval = { from: new Date().getTime() - 24 * 60 * 60 * 60 * 1000, to: new Date().getTime(), }) { console.log(timeInterval); const queryData = { from: timeInterval.from, to: timeInterval.to }; if (query) queryData.query = query; let getLogsRequest = new $Sls20201230.GetLogsRequest(queryData); let runtime = new $Util.RuntimeOptions({}); let headers = {}; try { return await this.client.getLogsWithOptions(this.project, log, getLogsRequest, headers, runtime); } catch (error) { console.log(error.message); console.log(error.data["Recommend"]); return []; } } async CreateSavedSearch(logs, sqlStr, name, displayName, topic) { let createSavedSearchRequest = new $Sls20201230.CreateSavedSearchRequest({ searchQuery: sqlStr, logstore: logs, topic: topic || logs, displayName: displayName, savedsearchName: name, }); let runtime = new $Util.RuntimeOptions({}); let headers = {}; try { await this.client.createSavedSearchWithOptions(this.project, createSavedSearchRequest, headers, runtime); } catch (error) { console.log(error.message); console.log(error.data["Recommend"]); return null; } } buildQuery(filter, sort) { let queryParts = []; // 处理过滤条件 for (const key in filter) { if (filter.hasOwnProperty(key)) { const value = filter[key]; if (typeof value === "string") { queryParts.push(`${key}='${value}'`); } else if (typeof value === "number") { queryParts.push(`${key}=${value}`); } else if (Array.isArray(value)) { queryParts.push(`${key} IN (${value.map((v) => `'${v}'`).join(", ")})`); } } } // 处理排序 if (sort) { queryParts.push(`ORDER BY ${sort.field} ${sort.order?.toUpperCase()}`); } // 组合查询条件 return queryParts.join(" AND "); } } exports.SLSLogSyncer = SLSLogSyncer;