@axiom-lattice/gateway 2.1.19 → 2.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
 
2
- > @axiom-lattice/gateway@2.1.19 build /home/runner/work/agentic/agentic/packages/gateway
2
+ > @axiom-lattice/gateway@2.1.20 build /home/runner/work/agentic/agentic/packages/gateway
3
3
  > tsup src/index.ts --format cjs,esm --dts --clean --sourcemap
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -9,13 +9,13 @@
9
9
  CLI Cleaning output folder
10
10
  CJS Build start
11
11
  ESM Build start
12
- ESM dist/index.mjs 61.30 KB
13
- ESM dist/index.mjs.map 132.19 KB
14
- ESM ⚡️ Build success in 147ms
15
- CJS dist/index.js 63.84 KB
16
- CJS dist/index.js.map 132.29 KB
17
- CJS ⚡️ Build success in 148ms
12
+ ESM dist/index.mjs 59.42 KB
13
+ ESM dist/index.mjs.map 129.40 KB
14
+ ESM ⚡️ Build success in 154ms
15
+ CJS dist/index.js 61.85 KB
16
+ CJS dist/index.js.map 129.46 KB
17
+ CJS ⚡️ Build success in 157ms
18
18
  DTS Build start
19
- DTS ⚡️ Build success in 7807ms
20
- DTS dist/index.d.ts 3.32 KB
21
- DTS dist/index.d.mts 3.32 KB
19
+ DTS ⚡️ Build success in 7579ms
20
+ DTS dist/index.d.ts 3.72 KB
21
+ DTS dist/index.d.mts 3.72 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @axiom-lattice/gateway
2
2
 
3
+ ## 2.1.20
4
+
5
+ ### Patch Changes
6
+
7
+ - ef0fb84: update lagger lattice
8
+ - Updated dependencies [ef0fb84]
9
+ - @axiom-lattice/protocols@2.1.9
10
+ - @axiom-lattice/core@2.1.15
11
+ - @axiom-lattice/queue-redis@1.0.8
12
+
3
13
  ## 2.1.19
4
14
 
5
15
  ### Patch Changes
@@ -0,0 +1,135 @@
1
+ # Logger Configuration Guide
2
+
3
+ Gateway 支持通过 `LatticeGatewayConfig` 自定义 logger 配置。
4
+
5
+ ## 默认配置
6
+
7
+ 如果不提供 `loggerConfig`,Gateway 会使用以下默认配置:
8
+
9
+ ```typescript
10
+ {
11
+ name: "default",
12
+ description: "Default logger for lattice-gateway service",
13
+ type: LoggerType.PINO,
14
+ serviceName: "lattice/gateway",
15
+ loggerName: "lattice/gateway",
16
+ file: {
17
+ file: "./logs/lattice/gateway",
18
+ frequency: "daily",
19
+ mkdir: true,
20
+ },
21
+ }
22
+ ```
23
+
24
+ ## 自定义配置示例
25
+
26
+ ### 示例 1: 自定义日志文件路径
27
+
28
+ ```typescript
29
+ import { LatticeGateway } from "@axiom-lattice/gateway";
30
+ import { LoggerType } from "@axiom-lattice/protocols";
31
+
32
+ LatticeGateway.startAsHttpEndpoint({
33
+ port: 4001,
34
+ loggerConfig: {
35
+ file: "./logs/my-custom-app.log", // 简单字符串路径
36
+ },
37
+ queueServiceConfig: {
38
+ type: "memory",
39
+ defaultStartPollingQueue: true,
40
+ },
41
+ });
42
+ ```
43
+
44
+ ### 示例 2: 详细文件配置
45
+
46
+ ```typescript
47
+ import { LatticeGateway } from "@axiom-lattice/gateway";
48
+ import { LoggerType } from "@axiom-lattice/protocols";
49
+
50
+ LatticeGateway.startAsHttpEndpoint({
51
+ port: 4001,
52
+ loggerConfig: {
53
+ serviceName: "my-service",
54
+ loggerName: "my-logger",
55
+ file: {
56
+ file: "./logs/my-service", // 文件路径(不含扩展名)
57
+ frequency: "daily", // 轮转频率: "daily" | "hourly" | "minutely"
58
+ mkdir: true, // 自动创建目录
59
+ maxFiles: 30, // 保留30天的日志文件
60
+ },
61
+ },
62
+ queueServiceConfig: {
63
+ type: "memory",
64
+ defaultStartPollingQueue: true,
65
+ },
66
+ });
67
+ ```
68
+
69
+ ### 示例 3: 使用控制台日志(开发环境)
70
+
71
+ ```typescript
72
+ import { LatticeGateway } from "@axiom-lattice/gateway";
73
+ import { LoggerType } from "@axiom-lattice/protocols";
74
+
75
+ LatticeGateway.startAsHttpEndpoint({
76
+ port: 4001,
77
+ loggerConfig: {
78
+ type: LoggerType.CONSOLE, // 使用控制台输出
79
+ serviceName: "my-service",
80
+ },
81
+ queueServiceConfig: {
82
+ type: "memory",
83
+ defaultStartPollingQueue: true,
84
+ },
85
+ });
86
+ ```
87
+
88
+ ### 示例 4: 仅覆盖部分配置
89
+
90
+ ```typescript
91
+ import { LatticeGateway } from "@axiom-lattice/gateway";
92
+
93
+ LatticeGateway.startAsHttpEndpoint({
94
+ port: 4001,
95
+ loggerConfig: {
96
+ // 只覆盖文件路径,其他使用默认值
97
+ file: "./logs/custom-path/app",
98
+ },
99
+ queueServiceConfig: {
100
+ type: "memory",
101
+ defaultStartPollingQueue: true,
102
+ },
103
+ });
104
+ ```
105
+
106
+ ## 配置选项说明
107
+
108
+ ### GatewayLoggerConfig
109
+
110
+ | 字段 | 类型 | 说明 | 默认值 |
111
+ |------|------|------|--------|
112
+ | `name` | `string?` | Logger 名称 | `"default"` |
113
+ | `description` | `string?` | Logger 描述 | `"Default logger for lattice-gateway service"` |
114
+ | `type` | `LoggerType?` | Logger 类型 | `LoggerType.PINO` |
115
+ | `serviceName` | `string?` | 服务名称 | `"lattice/gateway"` |
116
+ | `loggerName` | `string?` | Logger 实例名称 | `"lattice/gateway"` |
117
+ | `file` | `string \| PinoFileOptions?` | 文件路径或详细配置 | `{ file: "./logs/lattice/gateway", frequency: "daily", mkdir: true }` |
118
+ | `context` | `Record<string, any>?` | 初始上下文 | `{}` |
119
+
120
+ ### PinoFileOptions
121
+
122
+ | 字段 | 类型 | 说明 | 默认值 |
123
+ |------|------|------|--------|
124
+ | `file` | `string?` | 日志文件路径 | `"./logs/app"` |
125
+ | `frequency` | `"daily" \| "hourly" \| "minutely" \| string` | 日志轮转频率 | `"daily"` |
126
+ | `mkdir` | `boolean?` | 自动创建目录 | `true` |
127
+ | `size` | `string?` | 最大文件大小(如 "10M", "100K") | - |
128
+ | `maxFiles` | `number?` | 保留的最大文件数 | - |
129
+
130
+ ## 注意事项
131
+
132
+ 1. **配置合并**: 提供的 `loggerConfig` 会与默认配置合并,未指定的字段会使用默认值
133
+ 2. **文件路径**: 如果指定的是字符串路径,会自动使用默认的 `daily` 轮转策略
134
+ 3. **生产环境**: 在生产环境(`NODE_ENV=production`)下,如果没有指定 `file` 配置,会自动使用文件日志
135
+ 4. **开发环境**: 在开发环境下,如果没有指定 `file` 配置,会使用控制台输出(pino-pretty)
package/README.md CHANGED
@@ -8,7 +8,8 @@
8
8
  - 代理调用服务
9
9
  - 流式响应支持
10
10
  - 事件总线
11
- - 队列服务
11
+ - 队列服务(基于 QueueLattice)
12
+ - 日志服务(基于 LoggerLattice,支持自定义配置)
12
13
 
13
14
  ## 安装
14
15
 
@@ -89,6 +90,31 @@ console.log(result); // { success: true, message: "Configuration updated success
89
90
  - `GET /api/v1/run/:thread_id`: 获取运行状态
90
91
  - `GET /api/v1/run/:thread_id/messages`: 获取消息历史
91
92
 
93
+ ## Logger 配置
94
+
95
+ Gateway 使用 Logger Lattice 进行日志管理,支持自定义日志配置。详细说明请参考 [LOGGER_CONFIG.md](./LOGGER_CONFIG.md)。
96
+
97
+ ### 快速开始
98
+
99
+ ```typescript
100
+ import { LatticeGateway } from "@axiom-lattice/gateway";
101
+ import { LoggerType } from "@axiom-lattice/protocols";
102
+
103
+ // 使用默认配置
104
+ LatticeGateway.startAsHttpEndpoint({
105
+ port: 4001,
106
+ });
107
+
108
+ // 自定义日志配置
109
+ LatticeGateway.startAsHttpEndpoint({
110
+ port: 4001,
111
+ loggerConfig: {
112
+ file: "./logs/my-app/gateway",
113
+ serviceName: "my-service",
114
+ },
115
+ });
116
+ ```
117
+
92
118
  ## 目录结构
93
119
 
94
120
  - `src/config/`: 配置文件
@@ -96,3 +122,4 @@ console.log(result); // { success: true, message: "Configuration updated success
96
122
  - `src/routes/`: 路由定义
97
123
  - `src/services/`: 服务实现
98
124
  - `src/types/`: 类型定义
125
+ - `LOGGER_CONFIG.md`: Logger 配置详细文档
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as http from 'http';
2
2
  import * as fastify from 'fastify';
3
+ import { LoggerType, PinoFileOptions } from '@axiom-lattice/protocols';
3
4
 
4
5
  declare const defaultSwaggerConfig: {
5
6
  openapi: {
@@ -100,12 +101,25 @@ declare class AgentTaskConsumer {
100
101
  trigger_agent_task(taskRequest: AgentTaskRequest): void;
101
102
  }
102
103
 
104
+ /**
105
+ * Logger configuration for gateway
106
+ */
107
+ interface GatewayLoggerConfig {
108
+ name?: string;
109
+ description?: string;
110
+ type?: LoggerType;
111
+ serviceName?: string;
112
+ loggerName?: string;
113
+ file?: string | PinoFileOptions;
114
+ context?: Record<string, any>;
115
+ }
103
116
  interface LatticeGatewayConfig {
104
117
  port?: number;
105
118
  queueServiceConfig?: {
106
119
  type: QueueServiceType;
107
120
  defaultStartPollingQueue: boolean;
108
121
  };
122
+ loggerConfig?: Partial<GatewayLoggerConfig>;
109
123
  }
110
124
  declare const LatticeGateway: {
111
125
  startAsHttpEndpoint: (config?: LatticeGatewayConfig) => Promise<void>;
@@ -117,4 +131,4 @@ declare const LatticeGateway: {
117
131
  AgentTaskConsumer: typeof AgentTaskConsumer;
118
132
  };
119
133
 
120
- export { LatticeGateway, type LatticeGatewayConfig };
134
+ export { type GatewayLoggerConfig, LatticeGateway, type LatticeGatewayConfig };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as http from 'http';
2
2
  import * as fastify from 'fastify';
3
+ import { LoggerType, PinoFileOptions } from '@axiom-lattice/protocols';
3
4
 
4
5
  declare const defaultSwaggerConfig: {
5
6
  openapi: {
@@ -100,12 +101,25 @@ declare class AgentTaskConsumer {
100
101
  trigger_agent_task(taskRequest: AgentTaskRequest): void;
101
102
  }
102
103
 
104
+ /**
105
+ * Logger configuration for gateway
106
+ */
107
+ interface GatewayLoggerConfig {
108
+ name?: string;
109
+ description?: string;
110
+ type?: LoggerType;
111
+ serviceName?: string;
112
+ loggerName?: string;
113
+ file?: string | PinoFileOptions;
114
+ context?: Record<string, any>;
115
+ }
103
116
  interface LatticeGatewayConfig {
104
117
  port?: number;
105
118
  queueServiceConfig?: {
106
119
  type: QueueServiceType;
107
120
  defaultStartPollingQueue: boolean;
108
121
  };
122
+ loggerConfig?: Partial<GatewayLoggerConfig>;
109
123
  }
110
124
  declare const LatticeGateway: {
111
125
  startAsHttpEndpoint: (config?: LatticeGatewayConfig) => Promise<void>;
@@ -117,4 +131,4 @@ declare const LatticeGateway: {
117
131
  AgentTaskConsumer: typeof AgentTaskConsumer;
118
132
  };
119
133
 
120
- export { LatticeGateway, type LatticeGatewayConfig };
134
+ export { type GatewayLoggerConfig, LatticeGateway, type LatticeGatewayConfig };
package/dist/index.js CHANGED
@@ -1700,144 +1700,6 @@ var registerLatticeRoutes = (app2) => {
1700
1700
  app2.post("/api/schedules/:taskId/resume", resumeScheduledTask);
1701
1701
  };
1702
1702
 
1703
- // src/logger/Logger.ts
1704
- var import_pino = __toESM(require("pino"));
1705
- var import_pino_pretty = require("pino-pretty");
1706
- var import_pino_roll = require("pino-roll");
1707
- var PinoLoggerFactory = class _PinoLoggerFactory {
1708
- constructor() {
1709
- const isProd = process.env.NODE_ENV === "production";
1710
- const loggerConfig = {
1711
- // 自定义时间戳格式
1712
- timestamp: () => `,"@timestamp":"${(/* @__PURE__ */ new Date()).toISOString()}"`,
1713
- // 关闭默认的时间戳键
1714
- base: {
1715
- "@version": "1",
1716
- app_name: "lattice",
1717
- service_name: "lattice/graph-server",
1718
- thread_name: "main",
1719
- logger_name: "lattice-graph-logger"
1720
- },
1721
- formatters: {
1722
- level: (label, number) => {
1723
- return {
1724
- level: label.toUpperCase(),
1725
- level_value: number * 1e3
1726
- };
1727
- }
1728
- }
1729
- };
1730
- if (isProd) {
1731
- try {
1732
- this.pinoLogger = (0, import_pino.default)(
1733
- loggerConfig,
1734
- import_pino.default.transport({
1735
- target: "pino-roll",
1736
- options: {
1737
- file: "./logs/fin_ai_graph_server",
1738
- frequency: "daily",
1739
- mkdir: true
1740
- }
1741
- })
1742
- );
1743
- } catch (error) {
1744
- console.error(
1745
- "\u65E0\u6CD5\u521D\u59CB\u5316 pino-roll \u65E5\u5FD7\u8BB0\u5F55\u5668\uFF0C\u56DE\u9000\u5230\u63A7\u5236\u53F0\u65E5\u5FD7",
1746
- error
1747
- );
1748
- this.pinoLogger = (0, import_pino.default)({
1749
- ...loggerConfig,
1750
- transport: {
1751
- target: "pino-pretty",
1752
- options: {
1753
- colorize: true
1754
- }
1755
- }
1756
- });
1757
- }
1758
- } else {
1759
- this.pinoLogger = (0, import_pino.default)({
1760
- ...loggerConfig,
1761
- transport: {
1762
- target: "pino-pretty",
1763
- options: {
1764
- colorize: true
1765
- }
1766
- }
1767
- });
1768
- }
1769
- }
1770
- static getInstance() {
1771
- if (!_PinoLoggerFactory.instance) {
1772
- _PinoLoggerFactory.instance = new _PinoLoggerFactory();
1773
- }
1774
- return _PinoLoggerFactory.instance;
1775
- }
1776
- getPinoLogger() {
1777
- return this.pinoLogger;
1778
- }
1779
- };
1780
- var Logger = class _Logger {
1781
- constructor(options) {
1782
- this.context = options?.context || {};
1783
- this.name = options?.name || "lattice-graph-logger";
1784
- this.serviceName = options?.serviceName || "lattice/graph-server";
1785
- }
1786
- /**
1787
- * 获取合并了上下文的日志对象
1788
- * @param additionalContext 额外的上下文数据
1789
- * @returns 带有上下文的pino日志对象
1790
- */
1791
- getContextualLogger(additionalContext) {
1792
- const pinoLogger = PinoLoggerFactory.getInstance().getPinoLogger();
1793
- const contextObj = {
1794
- "x-user-id": this.context["x-user-id"] || "",
1795
- "x-tenant-id": this.context["x-tenant-id"] || "",
1796
- "x-request-id": this.context["x-request-id"] || "",
1797
- "x-task-id": this.context["x-task-id"] || "",
1798
- "x-thread-id": this.context["x-thread-id"] || "",
1799
- service_name: this.serviceName,
1800
- logger_name: this.name,
1801
- ...additionalContext
1802
- };
1803
- return pinoLogger.child(contextObj);
1804
- }
1805
- info(msg, obj) {
1806
- this.getContextualLogger(obj).info(msg);
1807
- }
1808
- error(msg, obj) {
1809
- this.getContextualLogger(obj).error(msg);
1810
- }
1811
- warn(msg, obj) {
1812
- this.getContextualLogger(obj).warn(msg);
1813
- }
1814
- debug(msg, obj) {
1815
- this.getContextualLogger(obj).debug(msg);
1816
- }
1817
- /**
1818
- * 更新Logger实例的上下文
1819
- */
1820
- updateContext(context) {
1821
- this.context = {
1822
- ...this.context,
1823
- ...context
1824
- };
1825
- }
1826
- /**
1827
- * 创建一个新的Logger实例,继承当前Logger的上下文
1828
- */
1829
- child(options) {
1830
- return new _Logger({
1831
- name: options.name || this.name,
1832
- serviceName: options.serviceName || this.serviceName,
1833
- context: {
1834
- ...this.context,
1835
- ...options.context
1836
- }
1837
- });
1838
- }
1839
- };
1840
-
1841
1703
  // src/swagger.ts
1842
1704
  var import_swagger = __toESM(require("@fastify/swagger"));
1843
1705
  var import_swagger_ui = __toESM(require("@fastify/swagger-ui"));
@@ -2183,13 +2045,27 @@ _AgentTaskConsumer.agent_run_endpoint = "http://localhost:4001/api/runs";
2183
2045
  var AgentTaskConsumer = _AgentTaskConsumer;
2184
2046
 
2185
2047
  // src/index.ts
2048
+ var import_core10 = require("@axiom-lattice/core");
2049
+ var import_protocols2 = require("@axiom-lattice/protocols");
2186
2050
  process.on("unhandledRejection", (reason, promise) => {
2187
2051
  console.error("\u672A\u5904\u7406\u7684Promise\u62D2\u7EDD:", reason);
2188
2052
  });
2189
- var logger = new Logger({
2190
- serviceName: "lattice-gateway",
2191
- name: "fastify-server"
2192
- });
2053
+ var DEFAULT_LOGGER_CONFIG = {
2054
+ name: "default",
2055
+ description: "Default logger for lattice-gateway service",
2056
+ type: import_protocols2.LoggerType.PINO,
2057
+ serviceName: "lattice/gateway",
2058
+ loggerName: "lattice/gateway"
2059
+ };
2060
+ var loggerLattice = initializeLogger(DEFAULT_LOGGER_CONFIG);
2061
+ var logger = loggerLattice.client;
2062
+ function initializeLogger(config) {
2063
+ if (import_core10.loggerLatticeManager.hasLattice("default")) {
2064
+ import_core10.loggerLatticeManager.removeLattice("default");
2065
+ }
2066
+ (0, import_core10.registerLoggerLattice)("default", config);
2067
+ return (0, import_core10.getLoggerLattice)("default");
2068
+ }
2193
2069
  var app = (0, import_fastify.default)({
2194
2070
  logger: false,
2195
2071
  // 禁用内置日志记录器
@@ -2197,17 +2073,33 @@ var app = (0, import_fastify.default)({
2197
2073
  // Default 50MB, configurable via BODY_LIMIT env var
2198
2074
  });
2199
2075
  app.addHook("onRequest", (request, reply, done) => {
2076
+ const getHeaderValue = (header) => {
2077
+ if (Array.isArray(header)) {
2078
+ return header[0];
2079
+ }
2080
+ return header;
2081
+ };
2200
2082
  const context = {
2201
- "x-tenant-id": request.headers["x-tenant-id"],
2202
- "x-request-id": request.headers["x-request-id"]
2083
+ "x-tenant-id": getHeaderValue(request.headers["x-tenant-id"]),
2084
+ "x-request-id": getHeaderValue(request.headers["x-request-id"])
2203
2085
  };
2086
+ if (loggerLattice.updateContext) {
2087
+ loggerLattice.updateContext(context);
2088
+ }
2204
2089
  done();
2205
2090
  });
2206
2091
  app.addHook("onResponse", (request, reply, done) => {
2092
+ const getHeaderValue = (header) => {
2093
+ if (Array.isArray(header)) {
2094
+ return header[0];
2095
+ }
2096
+ return header;
2097
+ };
2207
2098
  const context = {
2208
- "x-tenant-id": request.headers["x-tenant-id"],
2209
- "x-request-id": request.headers["x-request-id"]
2099
+ "x-tenant-id": getHeaderValue(request.headers["x-tenant-id"]),
2100
+ "x-request-id": getHeaderValue(request.headers["x-request-id"])
2210
2101
  };
2102
+ loggerLattice.info(`${request.method} ${request.url} - ${reply.statusCode}`);
2211
2103
  done();
2212
2104
  });
2213
2105
  app.register(import_cors.default, {
@@ -2225,9 +2117,15 @@ app.register(import_cors.default, {
2225
2117
  });
2226
2118
  app.register(import_sensible.default);
2227
2119
  app.setErrorHandler((error, request, reply) => {
2120
+ const getHeaderValue = (header) => {
2121
+ if (Array.isArray(header)) {
2122
+ return header[0];
2123
+ }
2124
+ return header;
2125
+ };
2228
2126
  const context = {
2229
- "x-tenant-id": request.headers["x-tenant-id"],
2230
- "x-request-id": request.headers["x-request-id"]
2127
+ "x-tenant-id": getHeaderValue(request.headers["x-tenant-id"]),
2128
+ "x-request-id": getHeaderValue(request.headers["x-request-id"])
2231
2129
  };
2232
2130
  logger.error(
2233
2131
  `\u8BF7\u6C42\u9519\u8BEF: ${request.method} ${request.url} error:${error.message}`,
@@ -2243,9 +2141,19 @@ app.setErrorHandler((error, request, reply) => {
2243
2141
  error: error.message || "\u670D\u52A1\u5668\u5185\u90E8\u9519\u8BEF"
2244
2142
  });
2245
2143
  });
2246
- app.decorate("logger", logger);
2247
2144
  var start = async (config) => {
2248
2145
  try {
2146
+ if (config?.loggerConfig) {
2147
+ const loggerConfig = {
2148
+ ...DEFAULT_LOGGER_CONFIG,
2149
+ ...config.loggerConfig,
2150
+ // Merge file config if provided
2151
+ file: config.loggerConfig.file || DEFAULT_LOGGER_CONFIG.file
2152
+ };
2153
+ loggerLattice = initializeLogger(loggerConfig);
2154
+ logger = loggerLattice.client;
2155
+ }
2156
+ app.decorate("loggerLattice", loggerLattice);
2249
2157
  const target_port = config?.port || Number(process.env.PORT) || 4001;
2250
2158
  await app.listen({ port: target_port, host: "0.0.0.0" });
2251
2159
  logger.info(`Lattice Gateway is running on port: ${target_port}`);