@degel_lc/logger 0.1.6 → 0.1.7
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.
- package/README.md +36 -10
- package/dist/chunk-3QE5XQOJ.cjs +144 -0
- package/dist/chunk-3QE5XQOJ.cjs.map +1 -0
- package/dist/{chunk-34MNPN6V.js → chunk-B7IDJBGL.js} +40 -5
- package/dist/chunk-B7IDJBGL.js.map +1 -0
- package/dist/index.cjs +142 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +196 -0
- package/dist/index.d.ts +40 -3
- package/dist/index.js +4 -15
- package/dist/index.js.map +1 -1
- package/dist/server-E7QYW63S.cjs +156 -0
- package/dist/server-E7QYW63S.cjs.map +1 -0
- package/dist/{server-J5UIJDX7.js → server-EIDMRA6K.js} +11 -20
- package/dist/server-EIDMRA6K.js.map +1 -0
- package/package.json +3 -2
- package/dist/chunk-34MNPN6V.js.map +0 -1
- package/dist/server-J5UIJDX7.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @degel_lc/logger
|
|
2
2
|
|
|
3
3
|
phsk関連プロジェクト共通のpino-basedロギングライブラリ。サーバーサイド・クライアントサイド両対応。
|
|
4
4
|
|
|
5
5
|
## インストール
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
pnpm add @
|
|
8
|
+
pnpm add @degel_lc/logger
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## 使用方法
|
|
@@ -13,7 +13,7 @@ pnpm add @phsk/logger
|
|
|
13
13
|
### 基本的な使用法(レガシー形式)
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
|
-
import { logger } from '@
|
|
16
|
+
import { logger } from '@degel_lc/logger';
|
|
17
17
|
|
|
18
18
|
// デバッグログ
|
|
19
19
|
logger.debug('デバッグ情報です', 'app.ts:10');
|
|
@@ -43,7 +43,7 @@ logger.sqlError('クエリ実行に失敗', 'userModel.ts:78', error);
|
|
|
43
43
|
APIリクエストのコンテキスト情報を含めたログ出力が可能です。
|
|
44
44
|
|
|
45
45
|
```typescript
|
|
46
|
-
import { logger } from '@
|
|
46
|
+
import { logger } from '@degel_lc/logger';
|
|
47
47
|
|
|
48
48
|
// コンテキスト付きログ
|
|
49
49
|
logger.info({ path: '/api/users', method: 'GET', userId: 'user123' }, 'ユーザー一覧取得');
|
|
@@ -64,7 +64,7 @@ logger.warn({ path: '/api/orders', orderId: 'order789' }, '在庫不足');
|
|
|
64
64
|
Next.jsなどのサーバーサイドアプリケーションでは、起動時に明示的に初期化することを推奨します。
|
|
65
65
|
|
|
66
66
|
```typescript
|
|
67
|
-
import { initializeLogger } from '@
|
|
67
|
+
import { initializeLogger } from '@degel_lc/logger';
|
|
68
68
|
|
|
69
69
|
// アプリケーション起動時
|
|
70
70
|
await initializeLogger({
|
|
@@ -77,7 +77,7 @@ await initializeLogger({
|
|
|
77
77
|
### カスタムロガーの作成
|
|
78
78
|
|
|
79
79
|
```typescript
|
|
80
|
-
import { createClientLogger, createServerLogger } from '@
|
|
80
|
+
import { createClientLogger, createServerLogger } from '@degel_lc/logger';
|
|
81
81
|
|
|
82
82
|
// クライアント用
|
|
83
83
|
const clientLogger = createClientLogger({
|
|
@@ -219,15 +219,41 @@ export async function register() {
|
|
|
219
219
|
|
|
220
220
|
このパッケージは Next.js(webpack/Turbopack)との互換性を考慮して設計されています。
|
|
221
221
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
### 必須設定(Next.jsプロジェクト)
|
|
223
|
+
|
|
224
|
+
**重要**: Next.jsで使用する場合、`next.config.ts`に以下の設定が必要です。
|
|
225
225
|
|
|
226
226
|
```typescript
|
|
227
|
-
//
|
|
227
|
+
// next.config.ts
|
|
228
|
+
const nextConfig: NextConfig = {
|
|
229
|
+
// @degel_lc/loggerをサーバーサイドでのみ解決し、クライアントバンドルから除外
|
|
230
|
+
serverExternalPackages: ['@degel_lc/logger'],
|
|
231
|
+
};
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
この設定により「Module not found: Can't resolve 'fs'」エラーを回避できます。
|
|
235
|
+
|
|
236
|
+
### 使用例
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
// instrumentation.ts - 静的インポートOK
|
|
228
240
|
import { initializeLogger, setSentryModule } from '@degel_lc/logger';
|
|
241
|
+
|
|
242
|
+
export async function register() {
|
|
243
|
+
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
|
244
|
+
await initializeLogger({ logDir: './logs', enableSentry: true });
|
|
245
|
+
}
|
|
246
|
+
}
|
|
229
247
|
```
|
|
230
248
|
|
|
249
|
+
### 技術的詳細
|
|
250
|
+
|
|
251
|
+
- **コード分割**: サーバー専用コード(`fs`/`path`モジュール使用)は別チャンクに分離
|
|
252
|
+
- **動的インポート**: `createServerLogger` は内部で動的インポートを使用
|
|
253
|
+
- **serverExternalPackages**: Next.jsがパッケージをNode.js `require`で解決し、クライアントバンドルから除外
|
|
254
|
+
|
|
255
|
+
**補足**: Next.jsは`pino`、`pino-pretty`などを自動的に除外リストに含めていますが、`@degel_lc/logger`のようなラッパーパッケージは手動で追加が必要です。
|
|
256
|
+
|
|
231
257
|
## 開発
|
|
232
258
|
|
|
233
259
|
```bash
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/constants.ts
|
|
4
|
+
var VALID_LOG_LEVELS = [
|
|
5
|
+
"debug",
|
|
6
|
+
"info",
|
|
7
|
+
"warn",
|
|
8
|
+
"error",
|
|
9
|
+
"fatal"
|
|
10
|
+
];
|
|
11
|
+
var LOG_LEVEL_PRIORITY = {
|
|
12
|
+
debug: 0,
|
|
13
|
+
info: 1,
|
|
14
|
+
warn: 2,
|
|
15
|
+
error: 3,
|
|
16
|
+
fatal: 4
|
|
17
|
+
};
|
|
18
|
+
var TIMEZONE = {
|
|
19
|
+
/** 日本標準時(JST)のUTCオフセット(分) */
|
|
20
|
+
JST_OFFSET_MINUTES: 540
|
|
21
|
+
};
|
|
22
|
+
var LOG_ROTATION = {
|
|
23
|
+
/** デフォルトのローテーションチェック間隔(ミリ秒): 1時間 */
|
|
24
|
+
DEFAULT_CHECK_INTERVAL_MS: 60 * 60 * 1e3
|
|
25
|
+
};
|
|
26
|
+
var LOG_FILE_PREFIX = {
|
|
27
|
+
DEBUG: "debug_log",
|
|
28
|
+
INFO: "info_log",
|
|
29
|
+
ERROR: "error_log",
|
|
30
|
+
FATAL: "fatal_log",
|
|
31
|
+
SQL_ERROR: "sql_error_log"
|
|
32
|
+
};
|
|
33
|
+
var LOG_MESSAGES = {
|
|
34
|
+
/** エラー情報がない場合のデフォルト表示 */
|
|
35
|
+
NO_ERROR: "\u306A\u3057"
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// src/utils.ts
|
|
39
|
+
var DEFAULT_TIMEZONE_OFFSET = TIMEZONE.JST_OFFSET_MINUTES;
|
|
40
|
+
function getCurrentDate(timezoneOffset = DEFAULT_TIMEZONE_OFFSET) {
|
|
41
|
+
const now = /* @__PURE__ */ new Date();
|
|
42
|
+
now.setTime(now.getTime() + timezoneOffset * 60 * 1e3);
|
|
43
|
+
const year = now.getUTCFullYear();
|
|
44
|
+
const month = String(now.getUTCMonth() + 1).padStart(2, "0");
|
|
45
|
+
const day = String(now.getUTCDate()).padStart(2, "0");
|
|
46
|
+
return `${year}_${month}_${day}`;
|
|
47
|
+
}
|
|
48
|
+
function getFormattedDateTime(timezoneOffset = DEFAULT_TIMEZONE_OFFSET) {
|
|
49
|
+
const now = /* @__PURE__ */ new Date();
|
|
50
|
+
now.setTime(now.getTime() + timezoneOffset * 60 * 1e3);
|
|
51
|
+
const year = now.getUTCFullYear();
|
|
52
|
+
const month = String(now.getUTCMonth() + 1).padStart(2, "0");
|
|
53
|
+
const day = String(now.getUTCDate()).padStart(2, "0");
|
|
54
|
+
const hours = String(now.getUTCHours()).padStart(2, "0");
|
|
55
|
+
const minutes = String(now.getUTCMinutes()).padStart(2, "0");
|
|
56
|
+
const seconds = String(now.getUTCSeconds()).padStart(2, "0");
|
|
57
|
+
return `${year}_${month}_${day} ${hours}:${minutes}:${seconds}`;
|
|
58
|
+
}
|
|
59
|
+
function formatLogMessage(level, message, location, originalError, timezoneOffset = DEFAULT_TIMEZONE_OFFSET) {
|
|
60
|
+
const formattedDate = getFormattedDateTime(timezoneOffset);
|
|
61
|
+
const errorType = level.toUpperCase();
|
|
62
|
+
const locationInfo = location ?? "Unknown";
|
|
63
|
+
const original = originalError ? originalError.toString() : originalError === null ? message : LOG_MESSAGES.NO_ERROR;
|
|
64
|
+
return `${formattedDate}\uFF1A${errorType}\uFF1A${message}\uFF1A${locationInfo}\uFF1A${original}`;
|
|
65
|
+
}
|
|
66
|
+
function isLogContext(arg) {
|
|
67
|
+
return typeof arg === "object" && arg !== null && !Array.isArray(arg) && typeof arg !== "string";
|
|
68
|
+
}
|
|
69
|
+
function formatContext(ctx) {
|
|
70
|
+
const parts = [];
|
|
71
|
+
if (ctx.path) parts.push(`path=${ctx.path}`);
|
|
72
|
+
if (ctx.method) parts.push(`method=${ctx.method}`);
|
|
73
|
+
if (ctx.userId) parts.push(`userId=${ctx.userId}`);
|
|
74
|
+
if (ctx.tenantId) parts.push(`tenantId=${ctx.tenantId}`);
|
|
75
|
+
if (ctx.location) parts.push(`location=${ctx.location}`);
|
|
76
|
+
for (const [key, value] of Object.entries(ctx)) {
|
|
77
|
+
if (!["path", "method", "userId", "tenantId", "location"].includes(key) && value !== void 0) {
|
|
78
|
+
parts.push(`${key}=${String(value)}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return parts.length > 0 ? `[${parts.join(", ")}]` : "";
|
|
82
|
+
}
|
|
83
|
+
function formatLogMessageWithContext(level, message, ctx, error, timezoneOffset = DEFAULT_TIMEZONE_OFFSET) {
|
|
84
|
+
const formattedDate = getFormattedDateTime(timezoneOffset);
|
|
85
|
+
const errorType = level.toUpperCase();
|
|
86
|
+
const contextInfo = formatContext(ctx);
|
|
87
|
+
let errorInfo = "";
|
|
88
|
+
if (error instanceof Error) {
|
|
89
|
+
errorInfo = ` | Error: ${error.message}`;
|
|
90
|
+
if (error.stack) {
|
|
91
|
+
errorInfo += `
|
|
92
|
+
${error.stack}`;
|
|
93
|
+
}
|
|
94
|
+
} else if (error !== void 0 && error !== null) {
|
|
95
|
+
errorInfo = ` | Error: ${String(error)}`;
|
|
96
|
+
}
|
|
97
|
+
const contextPart = contextInfo ? ` ${contextInfo}` : "";
|
|
98
|
+
return `${formattedDate}\uFF1A${errorType}\uFF1A${message}${contextPart}${errorInfo}`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/sentry.ts
|
|
102
|
+
var sentryModule = null;
|
|
103
|
+
function setSentryModule(sentry) {
|
|
104
|
+
sentryModule = sentry;
|
|
105
|
+
}
|
|
106
|
+
function isSentryEnabled() {
|
|
107
|
+
return sentryModule !== null;
|
|
108
|
+
}
|
|
109
|
+
function captureError(ctx, message, error) {
|
|
110
|
+
if (!sentryModule) return;
|
|
111
|
+
if (error instanceof Error) {
|
|
112
|
+
sentryModule.captureException(error, {
|
|
113
|
+
extra: {
|
|
114
|
+
...ctx,
|
|
115
|
+
message
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
} else if (error) {
|
|
119
|
+
sentryModule.captureMessage(`${message}: ${String(error)}`, {
|
|
120
|
+
level: "error",
|
|
121
|
+
extra: ctx
|
|
122
|
+
});
|
|
123
|
+
} else {
|
|
124
|
+
sentryModule.captureMessage(message, {
|
|
125
|
+
level: "error",
|
|
126
|
+
extra: ctx
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
exports.LOG_FILE_PREFIX = LOG_FILE_PREFIX;
|
|
132
|
+
exports.LOG_LEVEL_PRIORITY = LOG_LEVEL_PRIORITY;
|
|
133
|
+
exports.LOG_ROTATION = LOG_ROTATION;
|
|
134
|
+
exports.TIMEZONE = TIMEZONE;
|
|
135
|
+
exports.VALID_LOG_LEVELS = VALID_LOG_LEVELS;
|
|
136
|
+
exports.captureError = captureError;
|
|
137
|
+
exports.formatLogMessage = formatLogMessage;
|
|
138
|
+
exports.formatLogMessageWithContext = formatLogMessageWithContext;
|
|
139
|
+
exports.getCurrentDate = getCurrentDate;
|
|
140
|
+
exports.isLogContext = isLogContext;
|
|
141
|
+
exports.isSentryEnabled = isSentryEnabled;
|
|
142
|
+
exports.setSentryModule = setSentryModule;
|
|
143
|
+
//# sourceMappingURL=chunk-3QE5XQOJ.cjs.map
|
|
144
|
+
//# sourceMappingURL=chunk-3QE5XQOJ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/utils.ts","../src/sentry.ts"],"names":[],"mappings":";;;AAUO,IAAM,gBAAA,GAAwC;AAAA,EACnD,OAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF;AAMO,IAAM,kBAAA,GAA+C;AAAA,EAC1D,KAAA,EAAO,CAAA;AAAA,EACP,IAAA,EAAM,CAAA;AAAA,EACN,IAAA,EAAM,CAAA;AAAA,EACN,KAAA,EAAO,CAAA;AAAA,EACP,KAAA,EAAO;AACT;AAKO,IAAM,QAAA,GAAW;AAAA;AAAA,EAEtB,kBAAA,EAAoB;AACtB;AAKO,IAAM,YAAA,GAAe;AAAA;AAAA,EAE1B,yBAAA,EAA2B,KAAK,EAAA,GAAK;AACvC;AAKO,IAAM,eAAA,GAAkB;AAAA,EAC7B,KAAA,EAAO,WAAA;AAAA,EACP,IAAA,EAAM,UAAA;AAAA,EACN,KAAA,EAAO,WAAA;AAAA,EACP,KAAA,EAAO,WAAA;AAAA,EACP,SAAA,EAAW;AACb;AAKO,IAAM,YAAA,GAAe;AAAA;AAAA,EAE1B,QAAA,EAAU;AACZ,CAAA;;;AC5DA,IAAM,0BAA0B,QAAA,CAAS,kBAAA;AAKlC,SAAS,cAAA,CAAe,iBAAiB,uBAAA,EAAiC;AAC/E,EAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AACrB,EAAA,GAAA,CAAI,QAAQ,GAAA,CAAI,OAAA,EAAQ,GAAI,cAAA,GAAiB,KAAK,GAAI,CAAA;AAEtD,EAAA,MAAM,IAAA,GAAO,IAAI,cAAA,EAAe;AAChC,EAAA,MAAM,KAAA,GAAQ,OAAO,GAAA,CAAI,WAAA,KAAgB,CAAC,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAA;AAC3D,EAAA,MAAM,GAAA,GAAM,OAAO,GAAA,CAAI,UAAA,EAAY,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAEpD,EAAA,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAK,IAAI,GAAG,CAAA,CAAA;AAChC;AAKO,SAAS,oBAAA,CAAqB,iBAAiB,uBAAA,EAAiC;AACrF,EAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AACrB,EAAA,GAAA,CAAI,QAAQ,GAAA,CAAI,OAAA,EAAQ,GAAI,cAAA,GAAiB,KAAK,GAAI,CAAA;AAEtD,EAAA,MAAM,IAAA,GAAO,IAAI,cAAA,EAAe;AAChC,EAAA,MAAM,KAAA,GAAQ,OAAO,GAAA,CAAI,WAAA,KAAgB,CAAC,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAA;AAC3D,EAAA,MAAM,GAAA,GAAM,OAAO,GAAA,CAAI,UAAA,EAAY,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AACpD,EAAA,MAAM,KAAA,GAAQ,OAAO,GAAA,CAAI,WAAA,EAAa,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AACvD,EAAA,MAAM,OAAA,GAAU,OAAO,GAAA,CAAI,aAAA,EAAe,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAC3D,EAAA,MAAM,OAAA,GAAU,OAAO,GAAA,CAAI,aAAA,EAAe,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAE3D,EAAA,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;AAC/D;AAKO,SAAS,iBACd,KAAA,EACA,OAAA,EACA,QAAA,EACA,aAAA,EACA,iBAAiB,uBAAA,EACT;AACR,EAAA,MAAM,aAAA,GAAgB,qBAAqB,cAAc,CAAA;AACzD,EAAA,MAAM,SAAA,GAAY,MAAM,WAAA,EAAY;AACpC,EAAA,MAAM,eAAe,QAAA,IAAY,SAAA;AACjC,EAAA,MAAM,QAAA,GAAW,gBACb,aAAA,CAAc,QAAA,KACd,aAAA,KAAkB,IAAA,GAChB,UACA,YAAA,CAAa,QAAA;AAEnB,EAAA,OAAO,CAAA,EAAG,aAAa,CAAA,MAAA,EAAI,SAAS,SAAI,OAAO,CAAA,MAAA,EAAI,YAAY,CAAA,MAAA,EAAI,QAAQ,CAAA,CAAA;AAC7E;AAKO,SAAS,aAAa,GAAA,EAAiC;AAC5D,EAAA,OAAO,OAAO,GAAA,KAAQ,QAAA,IAAY,GAAA,KAAQ,IAAA,IAAQ,CAAC,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,IAAK,OAAO,GAAA,KAAQ,QAAA;AAC1F;AAKA,SAAS,cAAc,GAAA,EAAyB;AAC9C,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,IAAI,IAAI,IAAA,EAAM,KAAA,CAAM,KAAK,CAAA,KAAA,EAAQ,GAAA,CAAI,IAAI,CAAA,CAAE,CAAA;AAC3C,EAAA,IAAI,IAAI,MAAA,EAAQ,KAAA,CAAM,KAAK,CAAA,OAAA,EAAU,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AACjD,EAAA,IAAI,IAAI,MAAA,EAAQ,KAAA,CAAM,KAAK,CAAA,OAAA,EAAU,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AACjD,EAAA,IAAI,IAAI,QAAA,EAAU,KAAA,CAAM,KAAK,CAAA,SAAA,EAAY,GAAA,CAAI,QAAQ,CAAA,CAAE,CAAA;AACvD,EAAA,IAAI,IAAI,QAAA,EAAU,KAAA,CAAM,KAAK,CAAA,SAAA,EAAY,GAAA,CAAI,QAAQ,CAAA,CAAE,CAAA;AAGvD,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC9C,IAAA,IACE,CAAC,CAAC,MAAA,EAAQ,QAAA,EAAU,QAAA,EAAU,UAAA,EAAY,UAAU,CAAA,CAAE,QAAA,CAAS,GAAG,CAAA,IAClE,KAAA,KAAU,MAAA,EACV;AACA,MAAA,KAAA,CAAM,KAAK,CAAA,EAAG,GAAG,IAAI,MAAA,CAAO,KAAK,CAAC,CAAA,CAAE,CAAA;AAAA,IACtC;AAAA,EACF;AAEA,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,GAAI,CAAA,CAAA,EAAI,MAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA,GAAM,EAAA;AACtD;AAKO,SAAS,4BACd,KAAA,EACA,OAAA,EACA,GAAA,EACA,KAAA,EACA,iBAAiB,uBAAA,EACT;AACR,EAAA,MAAM,aAAA,GAAgB,qBAAqB,cAAc,CAAA;AACzD,EAAA,MAAM,SAAA,GAAY,MAAM,WAAA,EAAY;AACpC,EAAA,MAAM,WAAA,GAAc,cAAc,GAAG,CAAA;AAErC,EAAA,IAAI,SAAA,GAAY,EAAA;AAChB,EAAA,IAAI,iBAAiB,KAAA,EAAO;AAC1B,IAAA,SAAA,GAAY,CAAA,UAAA,EAAa,MAAM,OAAO,CAAA,CAAA;AACtC,IAAA,IAAI,MAAM,KAAA,EAAO;AACf,MAAA,SAAA,IAAa;AAAA,EAAK,MAAM,KAAK,CAAA,CAAA;AAAA,IAC/B;AAAA,EACF,CAAA,MAAA,IAAW,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AAChD,IAAA,SAAA,GAAY,CAAA,UAAA,EAAa,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA;AAAA,EACxC;AAEA,EAAA,MAAM,WAAA,GAAc,WAAA,GAAc,CAAA,CAAA,EAAI,WAAW,CAAA,CAAA,GAAK,EAAA;AACtD,EAAA,OAAO,CAAA,EAAG,aAAa,CAAA,MAAA,EAAI,SAAS,SAAI,OAAO,CAAA,EAAG,WAAW,CAAA,EAAG,SAAS,CAAA,CAAA;AAC3E;;;AC9GA,IAAI,YAAA,GAAoC,IAAA;AAKjC,SAAS,gBAAgB,MAAA,EAA4B;AAC1D,EAAA,YAAA,GAAe,MAAA;AACjB;AAKO,SAAS,eAAA,GAA2B;AACzC,EAAA,OAAO,YAAA,KAAiB,IAAA;AAC1B;AAYO,SAAS,YAAA,CAAa,GAAA,EAAiB,OAAA,EAAiB,KAAA,EAAuB;AACpF,EAAA,IAAI,CAAC,YAAA,EAAc;AAEnB,EAAA,IAAI,iBAAiB,KAAA,EAAO;AAC1B,IAAA,YAAA,CAAa,iBAAiB,KAAA,EAAO;AAAA,MACnC,KAAA,EAAO;AAAA,QACL,GAAG,GAAA;AAAA,QACH;AAAA;AACF,KACD,CAAA;AAAA,EACH,WAAW,KAAA,EAAO;AAChB,IAAA,YAAA,CAAa,eAAe,CAAA,EAAG,OAAO,KAAK,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA,EAAI;AAAA,MAC1D,KAAA,EAAO,OAAA;AAAA,MACP,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,EACH,CAAA,MAAO;AACL,IAAA,YAAA,CAAa,eAAe,OAAA,EAAS;AAAA,MACnC,KAAA,EAAO,OAAA;AAAA,MACP,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,EACH;AACF","file":"chunk-3QE5XQOJ.cjs","sourcesContent":["/**\n * ログレベル関連の定数\n */\n\nimport type { LogLevel } from './types.js';\n\n/**\n * 有効なログレベル一覧\n * LogLevel型と同期した配列\n */\nexport const VALID_LOG_LEVELS: readonly LogLevel[] = [\n 'debug',\n 'info',\n 'warn',\n 'error',\n 'fatal',\n] as const;\n\n/**\n * ログレベルの優先度マップ\n * 数値が大きいほど優先度が高い\n */\nexport const LOG_LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n fatal: 4,\n};\n\n/**\n * タイムゾーン関連\n */\nexport const TIMEZONE = {\n /** 日本標準時(JST)のUTCオフセット(分) */\n JST_OFFSET_MINUTES: 540 as number,\n};\n\n/**\n * ログローテーション関連\n */\nexport const LOG_ROTATION = {\n /** デフォルトのローテーションチェック間隔(ミリ秒): 1時間 */\n DEFAULT_CHECK_INTERVAL_MS: 60 * 60 * 1000,\n} as const;\n\n/**\n * ログファイル名プレフィックス\n */\nexport const LOG_FILE_PREFIX = {\n DEBUG: 'debug_log',\n INFO: 'info_log',\n ERROR: 'error_log',\n FATAL: 'fatal_log',\n SQL_ERROR: 'sql_error_log',\n} as const;\n\n/**\n * ログメッセージ関連の定数\n */\nexport const LOG_MESSAGES = {\n /** エラー情報がない場合のデフォルト表示 */\n NO_ERROR: 'なし',\n} as const;\n","import { LOG_MESSAGES, TIMEZONE } from './constants.js';\nimport type { LogContext } from './types.js';\n\nconst DEFAULT_TIMEZONE_OFFSET = TIMEZONE.JST_OFFSET_MINUTES;\n\n/**\n * 現在の日付を YYYY_MM_DD 形式で取得\n */\nexport function getCurrentDate(timezoneOffset = DEFAULT_TIMEZONE_OFFSET): string {\n const now = new Date();\n now.setTime(now.getTime() + timezoneOffset * 60 * 1000);\n\n const year = now.getUTCFullYear();\n const month = String(now.getUTCMonth() + 1).padStart(2, '0');\n const day = String(now.getUTCDate()).padStart(2, '0');\n\n return `${year}_${month}_${day}`;\n}\n\n/**\n * 現在の日時をフォーマットする(タイムゾーン調整付き)\n */\nexport function getFormattedDateTime(timezoneOffset = DEFAULT_TIMEZONE_OFFSET): string {\n const now = new Date();\n now.setTime(now.getTime() + timezoneOffset * 60 * 1000);\n\n const year = now.getUTCFullYear();\n const month = String(now.getUTCMonth() + 1).padStart(2, '0');\n const day = String(now.getUTCDate()).padStart(2, '0');\n const hours = String(now.getUTCHours()).padStart(2, '0');\n const minutes = String(now.getUTCMinutes()).padStart(2, '0');\n const seconds = String(now.getUTCSeconds()).padStart(2, '0');\n\n return `${year}_${month}_${day} ${hours}:${minutes}:${seconds}`;\n}\n\n/**\n * ログメッセージをフォーマットする\n */\nexport function formatLogMessage(\n level: string,\n message: string,\n location: string | null,\n originalError: Error | string | null,\n timezoneOffset = DEFAULT_TIMEZONE_OFFSET\n): string {\n const formattedDate = getFormattedDateTime(timezoneOffset);\n const errorType = level.toUpperCase();\n const locationInfo = location ?? 'Unknown';\n const original = originalError\n ? originalError.toString()\n : originalError === null\n ? message\n : LOG_MESSAGES.NO_ERROR;\n\n return `${formattedDate}:${errorType}:${message}:${locationInfo}:${original}`;\n}\n\n/**\n * 引数がLogContextかどうかを判定\n */\nexport function isLogContext(arg: unknown): arg is LogContext {\n return typeof arg === 'object' && arg !== null && !Array.isArray(arg) && typeof arg !== 'string';\n}\n\n/**\n * コンテキスト情報をフォーマットする\n */\nfunction formatContext(ctx: LogContext): string {\n const parts: string[] = [];\n\n if (ctx.path) parts.push(`path=${ctx.path}`);\n if (ctx.method) parts.push(`method=${ctx.method}`);\n if (ctx.userId) parts.push(`userId=${ctx.userId}`);\n if (ctx.tenantId) parts.push(`tenantId=${ctx.tenantId}`);\n if (ctx.location) parts.push(`location=${ctx.location}`);\n\n // その他のカスタムフィールド\n for (const [key, value] of Object.entries(ctx)) {\n if (\n !['path', 'method', 'userId', 'tenantId', 'location'].includes(key) &&\n value !== undefined\n ) {\n parts.push(`${key}=${String(value)}`);\n }\n }\n\n return parts.length > 0 ? `[${parts.join(', ')}]` : '';\n}\n\n/**\n * 構造化コンテキスト対応のログメッセージをフォーマットする\n */\nexport function formatLogMessageWithContext(\n level: string,\n message: string,\n ctx: LogContext,\n error: unknown,\n timezoneOffset = DEFAULT_TIMEZONE_OFFSET\n): string {\n const formattedDate = getFormattedDateTime(timezoneOffset);\n const errorType = level.toUpperCase();\n const contextInfo = formatContext(ctx);\n\n let errorInfo = '';\n if (error instanceof Error) {\n errorInfo = ` | Error: ${error.message}`;\n if (error.stack) {\n errorInfo += `\\n${error.stack}`;\n }\n } else if (error !== undefined && error !== null) {\n errorInfo = ` | Error: ${String(error)}`;\n }\n\n const contextPart = contextInfo ? ` ${contextInfo}` : '';\n return `${formattedDate}:${errorType}:${message}${contextPart}${errorInfo}`;\n}\n","/**\n * Sentry連携ヘルパー\n */\n\nimport type { LogContext, SentryModule } from './types.js';\n\nlet sentryModule: SentryModule | null = null;\n\n/**\n * Sentryモジュールを設定\n */\nexport function setSentryModule(sentry: SentryModule): void {\n sentryModule = sentry;\n}\n\n/**\n * Sentryが有効かどうか\n */\nexport function isSentryEnabled(): boolean {\n return sentryModule !== null;\n}\n\n/**\n * Sentryモジュールをクリア(テスト用)\n */\nexport function clearSentryModule(): void {\n sentryModule = null;\n}\n\n/**\n * エラーをSentryに送信\n */\nexport function captureError(ctx: LogContext, message: string, error?: unknown): void {\n if (!sentryModule) return;\n\n if (error instanceof Error) {\n sentryModule.captureException(error, {\n extra: {\n ...ctx,\n message,\n },\n });\n } else if (error) {\n sentryModule.captureMessage(`${message}: ${String(error)}`, {\n level: 'error',\n extra: ctx,\n });\n } else {\n sentryModule.captureMessage(message, {\n level: 'error',\n extra: ctx,\n });\n }\n}\n"]}
|
|
@@ -1,5 +1,40 @@
|
|
|
1
|
+
// src/constants.ts
|
|
2
|
+
var VALID_LOG_LEVELS = [
|
|
3
|
+
"debug",
|
|
4
|
+
"info",
|
|
5
|
+
"warn",
|
|
6
|
+
"error",
|
|
7
|
+
"fatal"
|
|
8
|
+
];
|
|
9
|
+
var LOG_LEVEL_PRIORITY = {
|
|
10
|
+
debug: 0,
|
|
11
|
+
info: 1,
|
|
12
|
+
warn: 2,
|
|
13
|
+
error: 3,
|
|
14
|
+
fatal: 4
|
|
15
|
+
};
|
|
16
|
+
var TIMEZONE = {
|
|
17
|
+
/** 日本標準時(JST)のUTCオフセット(分) */
|
|
18
|
+
JST_OFFSET_MINUTES: 540
|
|
19
|
+
};
|
|
20
|
+
var LOG_ROTATION = {
|
|
21
|
+
/** デフォルトのローテーションチェック間隔(ミリ秒): 1時間 */
|
|
22
|
+
DEFAULT_CHECK_INTERVAL_MS: 60 * 60 * 1e3
|
|
23
|
+
};
|
|
24
|
+
var LOG_FILE_PREFIX = {
|
|
25
|
+
DEBUG: "debug_log",
|
|
26
|
+
INFO: "info_log",
|
|
27
|
+
ERROR: "error_log",
|
|
28
|
+
FATAL: "fatal_log",
|
|
29
|
+
SQL_ERROR: "sql_error_log"
|
|
30
|
+
};
|
|
31
|
+
var LOG_MESSAGES = {
|
|
32
|
+
/** エラー情報がない場合のデフォルト表示 */
|
|
33
|
+
NO_ERROR: "\u306A\u3057"
|
|
34
|
+
};
|
|
35
|
+
|
|
1
36
|
// src/utils.ts
|
|
2
|
-
var DEFAULT_TIMEZONE_OFFSET =
|
|
37
|
+
var DEFAULT_TIMEZONE_OFFSET = TIMEZONE.JST_OFFSET_MINUTES;
|
|
3
38
|
function getCurrentDate(timezoneOffset = DEFAULT_TIMEZONE_OFFSET) {
|
|
4
39
|
const now = /* @__PURE__ */ new Date();
|
|
5
40
|
now.setTime(now.getTime() + timezoneOffset * 60 * 1e3);
|
|
@@ -23,7 +58,7 @@ function formatLogMessage(level, message, location, originalError, timezoneOffse
|
|
|
23
58
|
const formattedDate = getFormattedDateTime(timezoneOffset);
|
|
24
59
|
const errorType = level.toUpperCase();
|
|
25
60
|
const locationInfo = location ?? "Unknown";
|
|
26
|
-
const original = originalError ? originalError.toString() : originalError === null ? message :
|
|
61
|
+
const original = originalError ? originalError.toString() : originalError === null ? message : LOG_MESSAGES.NO_ERROR;
|
|
27
62
|
return `${formattedDate}\uFF1A${errorType}\uFF1A${message}\uFF1A${locationInfo}\uFF1A${original}`;
|
|
28
63
|
}
|
|
29
64
|
function isLogContext(arg) {
|
|
@@ -91,6 +126,6 @@ function captureError(ctx, message, error) {
|
|
|
91
126
|
}
|
|
92
127
|
}
|
|
93
128
|
|
|
94
|
-
export { captureError, formatLogMessage, formatLogMessageWithContext, getCurrentDate, isLogContext, isSentryEnabled, setSentryModule };
|
|
95
|
-
//# sourceMappingURL=chunk-
|
|
96
|
-
//# sourceMappingURL=chunk-
|
|
129
|
+
export { LOG_FILE_PREFIX, LOG_LEVEL_PRIORITY, LOG_ROTATION, TIMEZONE, VALID_LOG_LEVELS, captureError, formatLogMessage, formatLogMessageWithContext, getCurrentDate, isLogContext, isSentryEnabled, setSentryModule };
|
|
130
|
+
//# sourceMappingURL=chunk-B7IDJBGL.js.map
|
|
131
|
+
//# sourceMappingURL=chunk-B7IDJBGL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/utils.ts","../src/sentry.ts"],"names":[],"mappings":"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","file":"chunk-B7IDJBGL.js","sourcesContent":["/**\n * ログレベル関連の定数\n */\n\nimport type { LogLevel } from './types.js';\n\n/**\n * 有効なログレベル一覧\n * LogLevel型と同期した配列\n */\nexport const VALID_LOG_LEVELS: readonly LogLevel[] = [\n 'debug',\n 'info',\n 'warn',\n 'error',\n 'fatal',\n] as const;\n\n/**\n * ログレベルの優先度マップ\n * 数値が大きいほど優先度が高い\n */\nexport const LOG_LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n fatal: 4,\n};\n\n/**\n * タイムゾーン関連\n */\nexport const TIMEZONE = {\n /** 日本標準時(JST)のUTCオフセット(分) */\n JST_OFFSET_MINUTES: 540 as number,\n};\n\n/**\n * ログローテーション関連\n */\nexport const LOG_ROTATION = {\n /** デフォルトのローテーションチェック間隔(ミリ秒): 1時間 */\n DEFAULT_CHECK_INTERVAL_MS: 60 * 60 * 1000,\n} as const;\n\n/**\n * ログファイル名プレフィックス\n */\nexport const LOG_FILE_PREFIX = {\n DEBUG: 'debug_log',\n INFO: 'info_log',\n ERROR: 'error_log',\n FATAL: 'fatal_log',\n SQL_ERROR: 'sql_error_log',\n} as const;\n\n/**\n * ログメッセージ関連の定数\n */\nexport const LOG_MESSAGES = {\n /** エラー情報がない場合のデフォルト表示 */\n NO_ERROR: 'なし',\n} as const;\n","import { LOG_MESSAGES, TIMEZONE } from './constants.js';\nimport type { LogContext } from './types.js';\n\nconst DEFAULT_TIMEZONE_OFFSET = TIMEZONE.JST_OFFSET_MINUTES;\n\n/**\n * 現在の日付を YYYY_MM_DD 形式で取得\n */\nexport function getCurrentDate(timezoneOffset = DEFAULT_TIMEZONE_OFFSET): string {\n const now = new Date();\n now.setTime(now.getTime() + timezoneOffset * 60 * 1000);\n\n const year = now.getUTCFullYear();\n const month = String(now.getUTCMonth() + 1).padStart(2, '0');\n const day = String(now.getUTCDate()).padStart(2, '0');\n\n return `${year}_${month}_${day}`;\n}\n\n/**\n * 現在の日時をフォーマットする(タイムゾーン調整付き)\n */\nexport function getFormattedDateTime(timezoneOffset = DEFAULT_TIMEZONE_OFFSET): string {\n const now = new Date();\n now.setTime(now.getTime() + timezoneOffset * 60 * 1000);\n\n const year = now.getUTCFullYear();\n const month = String(now.getUTCMonth() + 1).padStart(2, '0');\n const day = String(now.getUTCDate()).padStart(2, '0');\n const hours = String(now.getUTCHours()).padStart(2, '0');\n const minutes = String(now.getUTCMinutes()).padStart(2, '0');\n const seconds = String(now.getUTCSeconds()).padStart(2, '0');\n\n return `${year}_${month}_${day} ${hours}:${minutes}:${seconds}`;\n}\n\n/**\n * ログメッセージをフォーマットする\n */\nexport function formatLogMessage(\n level: string,\n message: string,\n location: string | null,\n originalError: Error | string | null,\n timezoneOffset = DEFAULT_TIMEZONE_OFFSET\n): string {\n const formattedDate = getFormattedDateTime(timezoneOffset);\n const errorType = level.toUpperCase();\n const locationInfo = location ?? 'Unknown';\n const original = originalError\n ? originalError.toString()\n : originalError === null\n ? message\n : LOG_MESSAGES.NO_ERROR;\n\n return `${formattedDate}:${errorType}:${message}:${locationInfo}:${original}`;\n}\n\n/**\n * 引数がLogContextかどうかを判定\n */\nexport function isLogContext(arg: unknown): arg is LogContext {\n return typeof arg === 'object' && arg !== null && !Array.isArray(arg) && typeof arg !== 'string';\n}\n\n/**\n * コンテキスト情報をフォーマットする\n */\nfunction formatContext(ctx: LogContext): string {\n const parts: string[] = [];\n\n if (ctx.path) parts.push(`path=${ctx.path}`);\n if (ctx.method) parts.push(`method=${ctx.method}`);\n if (ctx.userId) parts.push(`userId=${ctx.userId}`);\n if (ctx.tenantId) parts.push(`tenantId=${ctx.tenantId}`);\n if (ctx.location) parts.push(`location=${ctx.location}`);\n\n // その他のカスタムフィールド\n for (const [key, value] of Object.entries(ctx)) {\n if (\n !['path', 'method', 'userId', 'tenantId', 'location'].includes(key) &&\n value !== undefined\n ) {\n parts.push(`${key}=${String(value)}`);\n }\n }\n\n return parts.length > 0 ? `[${parts.join(', ')}]` : '';\n}\n\n/**\n * 構造化コンテキスト対応のログメッセージをフォーマットする\n */\nexport function formatLogMessageWithContext(\n level: string,\n message: string,\n ctx: LogContext,\n error: unknown,\n timezoneOffset = DEFAULT_TIMEZONE_OFFSET\n): string {\n const formattedDate = getFormattedDateTime(timezoneOffset);\n const errorType = level.toUpperCase();\n const contextInfo = formatContext(ctx);\n\n let errorInfo = '';\n if (error instanceof Error) {\n errorInfo = ` | Error: ${error.message}`;\n if (error.stack) {\n errorInfo += `\\n${error.stack}`;\n }\n } else if (error !== undefined && error !== null) {\n errorInfo = ` | Error: ${String(error)}`;\n }\n\n const contextPart = contextInfo ? ` ${contextInfo}` : '';\n return `${formattedDate}:${errorType}:${message}${contextPart}${errorInfo}`;\n}\n","/**\n * Sentry連携ヘルパー\n */\n\nimport type { LogContext, SentryModule } from './types.js';\n\nlet sentryModule: SentryModule | null = null;\n\n/**\n * Sentryモジュールを設定\n */\nexport function setSentryModule(sentry: SentryModule): void {\n sentryModule = sentry;\n}\n\n/**\n * Sentryが有効かどうか\n */\nexport function isSentryEnabled(): boolean {\n return sentryModule !== null;\n}\n\n/**\n * Sentryモジュールをクリア(テスト用)\n */\nexport function clearSentryModule(): void {\n sentryModule = null;\n}\n\n/**\n * エラーをSentryに送信\n */\nexport function captureError(ctx: LogContext, message: string, error?: unknown): void {\n if (!sentryModule) return;\n\n if (error instanceof Error) {\n sentryModule.captureException(error, {\n extra: {\n ...ctx,\n message,\n },\n });\n } else if (error) {\n sentryModule.captureMessage(`${message}: ${String(error)}`, {\n level: 'error',\n extra: ctx,\n });\n } else {\n sentryModule.captureMessage(message, {\n level: 'error',\n extra: ctx,\n });\n }\n}\n"]}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var chunk3QE5XQOJ_cjs = require('./chunk-3QE5XQOJ.cjs');
|
|
6
|
+
|
|
7
|
+
// src/client.ts
|
|
8
|
+
function shouldLog(logLevel, minLevel) {
|
|
9
|
+
return chunk3QE5XQOJ_cjs.LOG_LEVEL_PRIORITY[logLevel] >= chunk3QE5XQOJ_cjs.LOG_LEVEL_PRIORITY[minLevel];
|
|
10
|
+
}
|
|
11
|
+
function createClientLogger(config = {}) {
|
|
12
|
+
const { timezoneOffset = 540, enableConsole = true, level = "debug" } = config;
|
|
13
|
+
const minLevel = chunk3QE5XQOJ_cjs.VALID_LOG_LEVELS.includes(level) ? level : "debug";
|
|
14
|
+
const logToConsole = (logLevel, displayLevel, consoleMethod, ctxOrMessage, messageOrLocation, errorOrOriginal) => {
|
|
15
|
+
if (!enableConsole) return;
|
|
16
|
+
if (!shouldLog(logLevel, minLevel)) return;
|
|
17
|
+
let formattedMessage;
|
|
18
|
+
if (chunk3QE5XQOJ_cjs.isLogContext(ctxOrMessage)) {
|
|
19
|
+
formattedMessage = chunk3QE5XQOJ_cjs.formatLogMessageWithContext(
|
|
20
|
+
displayLevel,
|
|
21
|
+
messageOrLocation ?? "",
|
|
22
|
+
ctxOrMessage,
|
|
23
|
+
errorOrOriginal,
|
|
24
|
+
timezoneOffset
|
|
25
|
+
);
|
|
26
|
+
} else {
|
|
27
|
+
formattedMessage = chunk3QE5XQOJ_cjs.formatLogMessage(
|
|
28
|
+
displayLevel,
|
|
29
|
+
ctxOrMessage,
|
|
30
|
+
messageOrLocation ?? null,
|
|
31
|
+
errorOrOriginal ?? null,
|
|
32
|
+
timezoneOffset
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
consoleMethod(formattedMessage);
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
debug: (ctxOrMessage, messageOrLocation, originalError) => {
|
|
39
|
+
logToConsole("debug", "debug", console.debug, ctxOrMessage, messageOrLocation, originalError);
|
|
40
|
+
},
|
|
41
|
+
info: (ctxOrMessage, messageOrLocation, originalError) => {
|
|
42
|
+
logToConsole("info", "info", console.info, ctxOrMessage, messageOrLocation, originalError);
|
|
43
|
+
},
|
|
44
|
+
warn: (ctxOrMessage, messageOrLocation, originalError) => {
|
|
45
|
+
logToConsole("warn", "warn", console.warn, ctxOrMessage, messageOrLocation, originalError);
|
|
46
|
+
},
|
|
47
|
+
error: (ctxOrMessage, messageOrLocation, originalError) => {
|
|
48
|
+
logToConsole("error", "error", console.error, ctxOrMessage, messageOrLocation, originalError);
|
|
49
|
+
},
|
|
50
|
+
fatal: (ctxOrMessage, messageOrLocation, originalError) => {
|
|
51
|
+
logToConsole("fatal", "fatal", console.error, ctxOrMessage, messageOrLocation, originalError);
|
|
52
|
+
},
|
|
53
|
+
sqlError: (message, location, originalError) => {
|
|
54
|
+
logToConsole("error", "sql_error", console.error, message, location, originalError);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/index.ts
|
|
60
|
+
async function createServerLogger(config) {
|
|
61
|
+
const { createServerLogger: create } = await import('./server-E7QYW63S.cjs');
|
|
62
|
+
return create(config);
|
|
63
|
+
}
|
|
64
|
+
function getLogger() {
|
|
65
|
+
if (globalThis.__DEGEL_LOGGER__) {
|
|
66
|
+
return globalThis.__DEGEL_LOGGER__;
|
|
67
|
+
}
|
|
68
|
+
if (typeof window !== "undefined") {
|
|
69
|
+
globalThis.__DEGEL_LOGGER__ = createClientLogger();
|
|
70
|
+
return globalThis.__DEGEL_LOGGER__;
|
|
71
|
+
}
|
|
72
|
+
if (!globalThis.__DEGEL_LOGGER_INITIALIZED__) {
|
|
73
|
+
return createClientLogger();
|
|
74
|
+
}
|
|
75
|
+
return globalThis.__DEGEL_LOGGER__ ?? createClientLogger();
|
|
76
|
+
}
|
|
77
|
+
async function initializeLogger(config) {
|
|
78
|
+
if (globalThis.__DEGEL_LOGGER__ && globalThis.__DEGEL_LOGGER_INITIALIZED__) {
|
|
79
|
+
return globalThis.__DEGEL_LOGGER__;
|
|
80
|
+
}
|
|
81
|
+
if (typeof window !== "undefined") {
|
|
82
|
+
globalThis.__DEGEL_LOGGER__ = createClientLogger(config);
|
|
83
|
+
} else {
|
|
84
|
+
globalThis.__DEGEL_LOGGER__ = await createServerLogger(config);
|
|
85
|
+
}
|
|
86
|
+
globalThis.__DEGEL_LOGGER_INITIALIZED__ = true;
|
|
87
|
+
return globalThis.__DEGEL_LOGGER__;
|
|
88
|
+
}
|
|
89
|
+
var logger = {
|
|
90
|
+
debug: (ctxOrMessage, messageOrLocation, originalError) => getLogger().debug(ctxOrMessage, messageOrLocation, originalError),
|
|
91
|
+
info: (ctxOrMessage, messageOrLocation, originalError) => getLogger().info(ctxOrMessage, messageOrLocation, originalError),
|
|
92
|
+
warn: (ctxOrMessage, messageOrLocation, originalError) => getLogger().warn(ctxOrMessage, messageOrLocation, originalError),
|
|
93
|
+
error: (ctxOrMessage, messageOrLocation, originalError) => getLogger().error(
|
|
94
|
+
ctxOrMessage,
|
|
95
|
+
messageOrLocation,
|
|
96
|
+
originalError
|
|
97
|
+
),
|
|
98
|
+
fatal: (ctxOrMessage, messageOrLocation, originalError) => getLogger().fatal(
|
|
99
|
+
ctxOrMessage,
|
|
100
|
+
messageOrLocation,
|
|
101
|
+
originalError
|
|
102
|
+
),
|
|
103
|
+
sqlError: (message, location, originalError) => getLogger().sqlError(message, location, originalError)
|
|
104
|
+
};
|
|
105
|
+
var index_default = logger;
|
|
106
|
+
|
|
107
|
+
Object.defineProperty(exports, "LOG_FILE_PREFIX", {
|
|
108
|
+
enumerable: true,
|
|
109
|
+
get: function () { return chunk3QE5XQOJ_cjs.LOG_FILE_PREFIX; }
|
|
110
|
+
});
|
|
111
|
+
Object.defineProperty(exports, "LOG_LEVEL_PRIORITY", {
|
|
112
|
+
enumerable: true,
|
|
113
|
+
get: function () { return chunk3QE5XQOJ_cjs.LOG_LEVEL_PRIORITY; }
|
|
114
|
+
});
|
|
115
|
+
Object.defineProperty(exports, "LOG_ROTATION", {
|
|
116
|
+
enumerable: true,
|
|
117
|
+
get: function () { return chunk3QE5XQOJ_cjs.LOG_ROTATION; }
|
|
118
|
+
});
|
|
119
|
+
Object.defineProperty(exports, "TIMEZONE", {
|
|
120
|
+
enumerable: true,
|
|
121
|
+
get: function () { return chunk3QE5XQOJ_cjs.TIMEZONE; }
|
|
122
|
+
});
|
|
123
|
+
Object.defineProperty(exports, "VALID_LOG_LEVELS", {
|
|
124
|
+
enumerable: true,
|
|
125
|
+
get: function () { return chunk3QE5XQOJ_cjs.VALID_LOG_LEVELS; }
|
|
126
|
+
});
|
|
127
|
+
Object.defineProperty(exports, "isSentryEnabled", {
|
|
128
|
+
enumerable: true,
|
|
129
|
+
get: function () { return chunk3QE5XQOJ_cjs.isSentryEnabled; }
|
|
130
|
+
});
|
|
131
|
+
Object.defineProperty(exports, "setSentryModule", {
|
|
132
|
+
enumerable: true,
|
|
133
|
+
get: function () { return chunk3QE5XQOJ_cjs.setSentryModule; }
|
|
134
|
+
});
|
|
135
|
+
exports.createClientLogger = createClientLogger;
|
|
136
|
+
exports.createServerLogger = createServerLogger;
|
|
137
|
+
exports.default = index_default;
|
|
138
|
+
exports.getLogger = getLogger;
|
|
139
|
+
exports.initializeLogger = initializeLogger;
|
|
140
|
+
exports.logger = logger;
|
|
141
|
+
//# sourceMappingURL=index.cjs.map
|
|
142
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/index.ts"],"names":["LOG_LEVEL_PRIORITY","VALID_LOG_LEVELS","isLogContext","formatLogMessageWithContext","formatLogMessage"],"mappings":"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","file":"index.cjs","sourcesContent":["import { LOG_LEVEL_PRIORITY, VALID_LOG_LEVELS } from './constants.js';\nimport type { LogContext, LogLevel, Logger, LoggerConfig } from './types.js';\nimport { formatLogMessage, formatLogMessageWithContext, isLogContext } from './utils.js';\n\n/**\n * 指定されたログレベルが最小レベル以上かどうかを判定\n */\nfunction shouldLog(logLevel: LogLevel, minLevel: LogLevel): boolean {\n return LOG_LEVEL_PRIORITY[logLevel] >= LOG_LEVEL_PRIORITY[minLevel];\n}\n\n/**\n * クライアントサイド用ロガーを作成\n */\nexport function createClientLogger(config: LoggerConfig = {}): Logger {\n const { timezoneOffset = 540, enableConsole = true, level = 'debug' } = config;\n\n // 有効なログレベルかどうかを検証\n const minLevel: LogLevel = VALID_LOG_LEVELS.includes(level) ? level : 'debug';\n\n const logToConsole = (\n logLevel: LogLevel,\n displayLevel: string,\n consoleMethod: (...args: unknown[]) => void,\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n errorOrOriginal?: unknown\n ): void => {\n if (!enableConsole) return;\n if (!shouldLog(logLevel, minLevel)) return;\n\n let formattedMessage: string;\n\n if (isLogContext(ctxOrMessage)) {\n // 構造化コンテキスト形式: (ctx, message, error?)\n formattedMessage = formatLogMessageWithContext(\n displayLevel,\n messageOrLocation ?? '',\n ctxOrMessage,\n errorOrOriginal,\n timezoneOffset\n );\n } else {\n // レガシー形式: (message, location?, originalError?)\n formattedMessage = formatLogMessage(\n displayLevel,\n ctxOrMessage,\n (messageOrLocation as string) ?? null,\n (errorOrOriginal as Error | string) ?? null,\n timezoneOffset\n );\n }\n\n consoleMethod(formattedMessage);\n };\n\n return {\n debug: (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n originalError?: unknown\n ) => {\n logToConsole('debug', 'debug', console.debug, ctxOrMessage, messageOrLocation, originalError);\n },\n info: (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n originalError?: unknown\n ) => {\n logToConsole('info', 'info', console.info, ctxOrMessage, messageOrLocation, originalError);\n },\n warn: (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n originalError?: unknown\n ) => {\n logToConsole('warn', 'warn', console.warn, ctxOrMessage, messageOrLocation, originalError);\n },\n error: (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n originalError?: unknown\n ) => {\n logToConsole('error', 'error', console.error, ctxOrMessage, messageOrLocation, originalError);\n },\n fatal: (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n originalError?: unknown\n ) => {\n logToConsole('fatal', 'fatal', console.error, ctxOrMessage, messageOrLocation, originalError);\n },\n sqlError: (\n message: string,\n location?: string | null,\n originalError?: Error | string | null\n ) => {\n // sqlErrorはerrorレベルとしてフィルタリング、表示はsql_error\n logToConsole('error', 'sql_error', console.error, message, location, originalError);\n },\n } as Logger;\n}\n","import { createClientLogger } from './client.js';\nimport type {\n LogContext,\n LogLevel,\n LogMethod,\n LogMethodWithContext,\n LogTypeConfig,\n Logger,\n LoggerConfig,\n SentryModule,\n} from './types.js';\n\nexport type {\n LogContext,\n Logger,\n LoggerConfig,\n LogLevel,\n LogMethod,\n LogMethodWithContext,\n LogTypeConfig,\n SentryModule,\n};\n\nexport { createClientLogger };\nexport { isSentryEnabled, setSentryModule } from './sentry.js';\n\n// Constants\nexport {\n LOG_FILE_PREFIX,\n LOG_LEVEL_PRIORITY,\n LOG_ROTATION,\n TIMEZONE,\n VALID_LOG_LEVELS,\n} from './constants.js';\n\n/**\n * サーバーサイド用ロガー作成関数(動的import)\n * Next.jsなどのバンドラーでクライアント用にバンドルされる際に\n * fsモジュールの解決エラーを防ぐため、動的importで提供\n */\nexport async function createServerLogger(config?: LoggerConfig): Promise<Logger> {\n const { createServerLogger: create } = await import('./server.js');\n return create(config);\n}\n\n/**\n * グローバルシングルトン用の型定義\n * Next.js開発モードでのモジュール分離問題を解決するため、\n * globalThisを使用してロガーインスタンスを共有する\n */\ndeclare global {\n // eslint-disable-next-line no-var\n var __DEGEL_LOGGER__: Logger | undefined;\n // eslint-disable-next-line no-var\n var __DEGEL_LOGGER_INITIALIZED__: boolean | undefined;\n}\n\n/**\n * 環境を判定してデフォルトのロガーを取得\n * サーバーサイドでは非同期初期化が必要なため、初回呼び出し時はクライアントロガーを返す\n */\nexport function getLogger(): Logger {\n // グローバルに初期化済みのロガーがあれば返す\n if (globalThis.__DEGEL_LOGGER__) {\n return globalThis.__DEGEL_LOGGER__;\n }\n\n // クライアントサイドの場合\n if (typeof window !== 'undefined') {\n globalThis.__DEGEL_LOGGER__ = createClientLogger();\n return globalThis.__DEGEL_LOGGER__;\n }\n\n // サーバーサイドだが未初期化の場合は一時的にクライアントロガーを返す\n // initializeLogger()を呼び出すことで正しく初期化される\n if (!globalThis.__DEGEL_LOGGER_INITIALIZED__) {\n return createClientLogger();\n }\n\n return globalThis.__DEGEL_LOGGER__ ?? createClientLogger();\n}\n\n/**\n * サーバーサイド用の非同期初期化\n * Next.js等で使用する場合、アプリケーション起動時に呼び出す\n */\nexport async function initializeLogger(config?: LoggerConfig): Promise<Logger> {\n // 既に初期化済みの場合は既存のロガーを返す\n if (globalThis.__DEGEL_LOGGER__ && globalThis.__DEGEL_LOGGER_INITIALIZED__) {\n return globalThis.__DEGEL_LOGGER__;\n }\n\n if (typeof window !== 'undefined') {\n globalThis.__DEGEL_LOGGER__ = createClientLogger(config);\n } else {\n globalThis.__DEGEL_LOGGER__ = await createServerLogger(config);\n }\n globalThis.__DEGEL_LOGGER_INITIALIZED__ = true;\n return globalThis.__DEGEL_LOGGER__;\n}\n\n/**\n * 共通ロガーオブジェクト(後方互換性のため)\n * サーバー/クライアントで自動的に適切なロガーを選択\n */\nexport const logger: Logger = {\n debug: (ctxOrMessage, messageOrLocation, originalError) =>\n getLogger().debug(ctxOrMessage as string, messageOrLocation, originalError),\n info: (ctxOrMessage, messageOrLocation, originalError) =>\n getLogger().info(ctxOrMessage as string, messageOrLocation, originalError),\n warn: (ctxOrMessage, messageOrLocation, originalError) =>\n getLogger().warn(ctxOrMessage as string, messageOrLocation, originalError),\n error: (ctxOrMessage, messageOrLocation, originalError) =>\n getLogger().error(\n ctxOrMessage as string,\n messageOrLocation,\n originalError as Error | string | null | undefined\n ),\n fatal: (ctxOrMessage, messageOrLocation, originalError) =>\n getLogger().fatal(\n ctxOrMessage as string,\n messageOrLocation,\n originalError as Error | string | null | undefined\n ),\n sqlError: (message, location, originalError) =>\n getLogger().sqlError(message, location, originalError),\n} as Logger;\n\nexport default logger;\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { Level } from 'pino';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ログコンテキスト(構造化ログ用)
|
|
5
|
+
*/
|
|
6
|
+
interface LogContext {
|
|
7
|
+
/** APIパス */
|
|
8
|
+
path?: string;
|
|
9
|
+
/** HTTPメソッド */
|
|
10
|
+
method?: string;
|
|
11
|
+
/** ユーザーID */
|
|
12
|
+
userId?: string;
|
|
13
|
+
/** テナントID */
|
|
14
|
+
tenantId?: string;
|
|
15
|
+
/** ファイル位置(レガシー互換) */
|
|
16
|
+
location?: string;
|
|
17
|
+
/** その他の任意データ */
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* ログメソッドのシグネチャ(レガシー形式)
|
|
22
|
+
*/
|
|
23
|
+
type LogMethod = (message: string, location?: string | null, originalError?: Error | string | null) => void;
|
|
24
|
+
/**
|
|
25
|
+
* ログメソッドのシグネチャ(構造化コンテキスト形式)
|
|
26
|
+
*/
|
|
27
|
+
type LogMethodWithContext = (ctx: LogContext, message: string, error?: unknown) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Loggerインターフェース(オーバーロード対応)
|
|
30
|
+
*/
|
|
31
|
+
interface Logger {
|
|
32
|
+
debug(ctx: LogContext, message: string): void;
|
|
33
|
+
info(ctx: LogContext, message: string): void;
|
|
34
|
+
warn(ctx: LogContext, message: string): void;
|
|
35
|
+
error(ctx: LogContext, message: string, error?: unknown): void;
|
|
36
|
+
fatal(ctx: LogContext, message: string, error?: unknown): void;
|
|
37
|
+
debug(message: string, location?: string | null, originalError?: Error | string | null): void;
|
|
38
|
+
info(message: string, location?: string | null, originalError?: Error | string | null): void;
|
|
39
|
+
warn(message: string, location?: string | null, originalError?: Error | string | null): void;
|
|
40
|
+
error(message: string, location?: string | null, originalError?: Error | string | null): void;
|
|
41
|
+
fatal(message: string, location?: string | null, originalError?: Error | string | null): void;
|
|
42
|
+
sqlError(message: string, location?: string | null, originalError?: Error | string | null): void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* ログレベル
|
|
46
|
+
*/
|
|
47
|
+
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal';
|
|
48
|
+
/**
|
|
49
|
+
* ログタイプの設定
|
|
50
|
+
*/
|
|
51
|
+
interface LogTypeConfig {
|
|
52
|
+
fileNamePrefix: string;
|
|
53
|
+
level: Level;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Sentryモジュールの型
|
|
57
|
+
* @sentry/node と @sentry/nextjs の両方で使用可能
|
|
58
|
+
* メソッド構文を使用して双変(bivariant)にし、型互換性を確保
|
|
59
|
+
*/
|
|
60
|
+
interface SentryModule {
|
|
61
|
+
/**
|
|
62
|
+
* 例外をSentryに送信
|
|
63
|
+
*/
|
|
64
|
+
captureException(error: unknown, hint?: {
|
|
65
|
+
extra?: Record<string, unknown>;
|
|
66
|
+
}): string;
|
|
67
|
+
/**
|
|
68
|
+
* メッセージをSentryに送信
|
|
69
|
+
*/
|
|
70
|
+
captureMessage(message: string, captureContext?: unknown): string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* ロガー設定オプション
|
|
74
|
+
*/
|
|
75
|
+
interface LoggerConfig {
|
|
76
|
+
/**
|
|
77
|
+
* ログ出力ディレクトリ(サーバーサイドのみ)
|
|
78
|
+
* デフォルト: process.cwd() + '/logs'
|
|
79
|
+
*/
|
|
80
|
+
logDir?: string;
|
|
81
|
+
/**
|
|
82
|
+
* 最小ログレベル
|
|
83
|
+
* デフォルト: 'debug'
|
|
84
|
+
*/
|
|
85
|
+
level?: LogLevel;
|
|
86
|
+
/**
|
|
87
|
+
* ログローテーションのチェック間隔(ミリ秒)
|
|
88
|
+
* デフォルト: 3600000 (1時間)
|
|
89
|
+
*/
|
|
90
|
+
rotationCheckInterval?: number;
|
|
91
|
+
/**
|
|
92
|
+
* タイムゾーンオフセット(分)
|
|
93
|
+
* デフォルト: 540 (JST = UTC+9)
|
|
94
|
+
*/
|
|
95
|
+
timezoneOffset?: number;
|
|
96
|
+
/**
|
|
97
|
+
* クライアントサイドでコンソール出力を有効化
|
|
98
|
+
* デフォルト: true
|
|
99
|
+
*/
|
|
100
|
+
enableConsole?: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Sentry連携を有効化
|
|
103
|
+
* @default false
|
|
104
|
+
*/
|
|
105
|
+
enableSentry?: boolean;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* クライアントサイド用ロガーを作成
|
|
110
|
+
*/
|
|
111
|
+
declare function createClientLogger(config?: LoggerConfig): Logger;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Sentry連携ヘルパー
|
|
115
|
+
*/
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Sentryモジュールを設定
|
|
119
|
+
*/
|
|
120
|
+
declare function setSentryModule(sentry: SentryModule): void;
|
|
121
|
+
/**
|
|
122
|
+
* Sentryが有効かどうか
|
|
123
|
+
*/
|
|
124
|
+
declare function isSentryEnabled(): boolean;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* ログレベル関連の定数
|
|
128
|
+
*/
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* 有効なログレベル一覧
|
|
132
|
+
* LogLevel型と同期した配列
|
|
133
|
+
*/
|
|
134
|
+
declare const VALID_LOG_LEVELS: readonly LogLevel[];
|
|
135
|
+
/**
|
|
136
|
+
* ログレベルの優先度マップ
|
|
137
|
+
* 数値が大きいほど優先度が高い
|
|
138
|
+
*/
|
|
139
|
+
declare const LOG_LEVEL_PRIORITY: Record<LogLevel, number>;
|
|
140
|
+
/**
|
|
141
|
+
* タイムゾーン関連
|
|
142
|
+
*/
|
|
143
|
+
declare const TIMEZONE: {
|
|
144
|
+
/** 日本標準時(JST)のUTCオフセット(分) */
|
|
145
|
+
JST_OFFSET_MINUTES: number;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* ログローテーション関連
|
|
149
|
+
*/
|
|
150
|
+
declare const LOG_ROTATION: {
|
|
151
|
+
/** デフォルトのローテーションチェック間隔(ミリ秒): 1時間 */
|
|
152
|
+
readonly DEFAULT_CHECK_INTERVAL_MS: number;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* ログファイル名プレフィックス
|
|
156
|
+
*/
|
|
157
|
+
declare const LOG_FILE_PREFIX: {
|
|
158
|
+
readonly DEBUG: "debug_log";
|
|
159
|
+
readonly INFO: "info_log";
|
|
160
|
+
readonly ERROR: "error_log";
|
|
161
|
+
readonly FATAL: "fatal_log";
|
|
162
|
+
readonly SQL_ERROR: "sql_error_log";
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* サーバーサイド用ロガー作成関数(動的import)
|
|
167
|
+
* Next.jsなどのバンドラーでクライアント用にバンドルされる際に
|
|
168
|
+
* fsモジュールの解決エラーを防ぐため、動的importで提供
|
|
169
|
+
*/
|
|
170
|
+
declare function createServerLogger(config?: LoggerConfig): Promise<Logger>;
|
|
171
|
+
/**
|
|
172
|
+
* グローバルシングルトン用の型定義
|
|
173
|
+
* Next.js開発モードでのモジュール分離問題を解決するため、
|
|
174
|
+
* globalThisを使用してロガーインスタンスを共有する
|
|
175
|
+
*/
|
|
176
|
+
declare global {
|
|
177
|
+
var __DEGEL_LOGGER__: Logger | undefined;
|
|
178
|
+
var __DEGEL_LOGGER_INITIALIZED__: boolean | undefined;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* 環境を判定してデフォルトのロガーを取得
|
|
182
|
+
* サーバーサイドでは非同期初期化が必要なため、初回呼び出し時はクライアントロガーを返す
|
|
183
|
+
*/
|
|
184
|
+
declare function getLogger(): Logger;
|
|
185
|
+
/**
|
|
186
|
+
* サーバーサイド用の非同期初期化
|
|
187
|
+
* Next.js等で使用する場合、アプリケーション起動時に呼び出す
|
|
188
|
+
*/
|
|
189
|
+
declare function initializeLogger(config?: LoggerConfig): Promise<Logger>;
|
|
190
|
+
/**
|
|
191
|
+
* 共通ロガーオブジェクト(後方互換性のため)
|
|
192
|
+
* サーバー/クライアントで自動的に適切なロガーを選択
|
|
193
|
+
*/
|
|
194
|
+
declare const logger: Logger;
|
|
195
|
+
|
|
196
|
+
export { LOG_FILE_PREFIX, LOG_LEVEL_PRIORITY, LOG_ROTATION, type LogContext, type LogLevel, type LogMethod, type LogMethodWithContext, type LogTypeConfig, type Logger, type LoggerConfig, type SentryModule, TIMEZONE, VALID_LOG_LEVELS, createClientLogger, createServerLogger, logger as default, getLogger, initializeLogger, isSentryEnabled, logger, setSentryModule };
|
package/dist/index.d.ts
CHANGED
|
@@ -123,12 +123,49 @@ declare function setSentryModule(sentry: SentryModule): void;
|
|
|
123
123
|
*/
|
|
124
124
|
declare function isSentryEnabled(): boolean;
|
|
125
125
|
|
|
126
|
+
/**
|
|
127
|
+
* ログレベル関連の定数
|
|
128
|
+
*/
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* 有効なログレベル一覧
|
|
132
|
+
* LogLevel型と同期した配列
|
|
133
|
+
*/
|
|
134
|
+
declare const VALID_LOG_LEVELS: readonly LogLevel[];
|
|
135
|
+
/**
|
|
136
|
+
* ログレベルの優先度マップ
|
|
137
|
+
* 数値が大きいほど優先度が高い
|
|
138
|
+
*/
|
|
139
|
+
declare const LOG_LEVEL_PRIORITY: Record<LogLevel, number>;
|
|
140
|
+
/**
|
|
141
|
+
* タイムゾーン関連
|
|
142
|
+
*/
|
|
143
|
+
declare const TIMEZONE: {
|
|
144
|
+
/** 日本標準時(JST)のUTCオフセット(分) */
|
|
145
|
+
JST_OFFSET_MINUTES: number;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* ログローテーション関連
|
|
149
|
+
*/
|
|
150
|
+
declare const LOG_ROTATION: {
|
|
151
|
+
/** デフォルトのローテーションチェック間隔(ミリ秒): 1時間 */
|
|
152
|
+
readonly DEFAULT_CHECK_INTERVAL_MS: number;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* ログファイル名プレフィックス
|
|
156
|
+
*/
|
|
157
|
+
declare const LOG_FILE_PREFIX: {
|
|
158
|
+
readonly DEBUG: "debug_log";
|
|
159
|
+
readonly INFO: "info_log";
|
|
160
|
+
readonly ERROR: "error_log";
|
|
161
|
+
readonly FATAL: "fatal_log";
|
|
162
|
+
readonly SQL_ERROR: "sql_error_log";
|
|
163
|
+
};
|
|
164
|
+
|
|
126
165
|
/**
|
|
127
166
|
* サーバーサイド用ロガー作成関数(動的import)
|
|
128
167
|
* Next.jsなどのバンドラーでクライアント用にバンドルされる際に
|
|
129
168
|
* fsモジュールの解決エラーを防ぐため、動的importで提供
|
|
130
|
-
*
|
|
131
|
-
* webpackIgnoreコメントにより、webpackがこのimportを解析・バンドルしない
|
|
132
169
|
*/
|
|
133
170
|
declare function createServerLogger(config?: LoggerConfig): Promise<Logger>;
|
|
134
171
|
/**
|
|
@@ -156,4 +193,4 @@ declare function initializeLogger(config?: LoggerConfig): Promise<Logger>;
|
|
|
156
193
|
*/
|
|
157
194
|
declare const logger: Logger;
|
|
158
195
|
|
|
159
|
-
export { type LogContext, type LogLevel, type LogMethod, type LogMethodWithContext, type LogTypeConfig, type Logger, type LoggerConfig, type SentryModule, createClientLogger, createServerLogger, logger as default, getLogger, initializeLogger, isSentryEnabled, logger, setSentryModule };
|
|
196
|
+
export { LOG_FILE_PREFIX, LOG_LEVEL_PRIORITY, LOG_ROTATION, type LogContext, type LogLevel, type LogMethod, type LogMethodWithContext, type LogTypeConfig, type Logger, type LoggerConfig, type SentryModule, TIMEZONE, VALID_LOG_LEVELS, createClientLogger, createServerLogger, logger as default, getLogger, initializeLogger, isSentryEnabled, logger, setSentryModule };
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
import { isLogContext, formatLogMessageWithContext, formatLogMessage } from './chunk-
|
|
2
|
-
export { isSentryEnabled, setSentryModule } from './chunk-
|
|
1
|
+
import { VALID_LOG_LEVELS, isLogContext, formatLogMessageWithContext, formatLogMessage, LOG_LEVEL_PRIORITY } from './chunk-B7IDJBGL.js';
|
|
2
|
+
export { LOG_FILE_PREFIX, LOG_LEVEL_PRIORITY, LOG_ROTATION, TIMEZONE, VALID_LOG_LEVELS, isSentryEnabled, setSentryModule } from './chunk-B7IDJBGL.js';
|
|
3
3
|
|
|
4
4
|
// src/client.ts
|
|
5
|
-
var LOG_LEVEL_PRIORITY = {
|
|
6
|
-
debug: 0,
|
|
7
|
-
info: 1,
|
|
8
|
-
warn: 2,
|
|
9
|
-
error: 3,
|
|
10
|
-
fatal: 4
|
|
11
|
-
};
|
|
12
5
|
function shouldLog(logLevel, minLevel) {
|
|
13
6
|
return LOG_LEVEL_PRIORITY[logLevel] >= LOG_LEVEL_PRIORITY[minLevel];
|
|
14
7
|
}
|
|
15
8
|
function createClientLogger(config = {}) {
|
|
16
9
|
const { timezoneOffset = 540, enableConsole = true, level = "debug" } = config;
|
|
17
|
-
const
|
|
18
|
-
const minLevel = validLevels.includes(level) ? level : "debug";
|
|
10
|
+
const minLevel = VALID_LOG_LEVELS.includes(level) ? level : "debug";
|
|
19
11
|
const logToConsole = (logLevel, displayLevel, consoleMethod, ctxOrMessage, messageOrLocation, errorOrOriginal) => {
|
|
20
12
|
if (!enableConsole) return;
|
|
21
13
|
if (!shouldLog(logLevel, minLevel)) return;
|
|
@@ -63,10 +55,7 @@ function createClientLogger(config = {}) {
|
|
|
63
55
|
|
|
64
56
|
// src/index.ts
|
|
65
57
|
async function createServerLogger(config) {
|
|
66
|
-
const { createServerLogger: create } = await import(
|
|
67
|
-
/* webpackIgnore: true */
|
|
68
|
-
'./server-J5UIJDX7.js'
|
|
69
|
-
);
|
|
58
|
+
const { createServerLogger: create } = await import('./server-EIDMRA6K.js');
|
|
70
59
|
return create(config);
|
|
71
60
|
}
|
|
72
61
|
function getLogger() {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { LogContext, LogLevel, Logger, LoggerConfig } from './types.js';\nimport { formatLogMessage, formatLogMessageWithContext, isLogContext } from './utils.js';\n\n// ログレベルの優先度マップ\nconst LOG_LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n fatal: 4,\n};\n\n/**\n * 指定されたログレベルが最小レベル以上かどうかを判定\n */\nfunction shouldLog(logLevel: LogLevel, minLevel: LogLevel): boolean {\n return LOG_LEVEL_PRIORITY[logLevel] >= LOG_LEVEL_PRIORITY[minLevel];\n}\n\n/**\n * クライアントサイド用ロガーを作成\n */\nexport function createClientLogger(config: LoggerConfig = {}): Logger {\n const { timezoneOffset = 540, enableConsole = true, level = 'debug' } = config;\n\n // 有効なログレベルかどうかを検証\n const validLevels: LogLevel[] = ['debug', 'info', 'warn', 'error', 'fatal'];\n const minLevel: LogLevel = validLevels.includes(level) ? level : 'debug';\n\n const logToConsole = (\n logLevel: LogLevel,\n displayLevel: string,\n consoleMethod: (...args: unknown[]) => void,\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n errorOrOriginal?: unknown\n ): void => {\n if (!enableConsole) return;\n if (!shouldLog(logLevel, minLevel)) return;\n\n let formattedMessage: string;\n\n if (isLogContext(ctxOrMessage)) {\n // 構造化コンテキスト形式: (ctx, message, error?)\n formattedMessage = formatLogMessageWithContext(\n displayLevel,\n messageOrLocation ?? '',\n ctxOrMessage,\n errorOrOriginal,\n timezoneOffset\n );\n } else {\n // レガシー形式: (message, location?, originalError?)\n formattedMessage = formatLogMessage(\n displayLevel,\n ctxOrMessage,\n (messageOrLocation as string) ?? null,\n (errorOrOriginal as Error | string) ?? null,\n timezoneOffset\n );\n }\n\n consoleMethod(formattedMessage);\n };\n\n return {\n debug: (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n originalError?: unknown\n ) => {\n logToConsole('debug', 'debug', console.debug, ctxOrMessage, messageOrLocation, originalError);\n },\n info: (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n originalError?: unknown\n ) => {\n logToConsole('info', 'info', console.info, ctxOrMessage, messageOrLocation, originalError);\n },\n warn: (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n originalError?: unknown\n ) => {\n logToConsole('warn', 'warn', console.warn, ctxOrMessage, messageOrLocation, originalError);\n },\n error: (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n originalError?: unknown\n ) => {\n logToConsole('error', 'error', console.error, ctxOrMessage, messageOrLocation, originalError);\n },\n fatal: (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n originalError?: unknown\n ) => {\n logToConsole('fatal', 'fatal', console.error, ctxOrMessage, messageOrLocation, originalError);\n },\n sqlError: (\n message: string,\n location?: string | null,\n originalError?: Error | string | null\n ) => {\n // sqlErrorはerrorレベルとしてフィルタリング、表示はsql_error\n logToConsole('error', 'sql_error', console.error, message, location, originalError);\n },\n } as Logger;\n}\n","import { createClientLogger } from './client.js';\nimport type {\n LogContext,\n LogLevel,\n LogMethod,\n LogMethodWithContext,\n LogTypeConfig,\n Logger,\n LoggerConfig,\n SentryModule,\n} from './types.js';\n\nexport type {\n LogContext,\n Logger,\n LoggerConfig,\n LogLevel,\n LogMethod,\n LogMethodWithContext,\n LogTypeConfig,\n SentryModule,\n};\n\nexport { createClientLogger };\nexport { isSentryEnabled, setSentryModule } from './sentry.js';\n\n/**\n * サーバーサイド用ロガー作成関数(動的import)\n * Next.jsなどのバンドラーでクライアント用にバンドルされる際に\n * fsモジュールの解決エラーを防ぐため、動的importで提供\n *\n * webpackIgnoreコメントにより、webpackがこのimportを解析・バンドルしない\n */\nexport async function createServerLogger(\n config?: LoggerConfig\n): Promise<Logger> {\n const { createServerLogger: create } = await import(/* webpackIgnore: true */ './server.js');\n return create(config);\n}\n\n/**\n * グローバルシングルトン用の型定義\n * Next.js開発モードでのモジュール分離問題を解決するため、\n * globalThisを使用してロガーインスタンスを共有する\n */\ndeclare global {\n // eslint-disable-next-line no-var\n var __DEGEL_LOGGER__: Logger | undefined;\n // eslint-disable-next-line no-var\n var __DEGEL_LOGGER_INITIALIZED__: boolean | undefined;\n}\n\n/**\n * 環境を判定してデフォルトのロガーを取得\n * サーバーサイドでは非同期初期化が必要なため、初回呼び出し時はクライアントロガーを返す\n */\nexport function getLogger(): Logger {\n // グローバルに初期化済みのロガーがあれば返す\n if (globalThis.__DEGEL_LOGGER__) {\n return globalThis.__DEGEL_LOGGER__;\n }\n\n // クライアントサイドの場合\n if (typeof window !== 'undefined') {\n globalThis.__DEGEL_LOGGER__ = createClientLogger();\n return globalThis.__DEGEL_LOGGER__;\n }\n\n // サーバーサイドだが未初期化の場合は一時的にクライアントロガーを返す\n // initializeLogger()を呼び出すことで正しく初期化される\n if (!globalThis.__DEGEL_LOGGER_INITIALIZED__) {\n return createClientLogger();\n }\n\n return globalThis.__DEGEL_LOGGER__ ?? createClientLogger();\n}\n\n/**\n * サーバーサイド用の非同期初期化\n * Next.js等で使用する場合、アプリケーション起動時に呼び出す\n */\nexport async function initializeLogger(config?: LoggerConfig): Promise<Logger> {\n // 既に初期化済みの場合は既存のロガーを返す\n if (globalThis.__DEGEL_LOGGER__ && globalThis.__DEGEL_LOGGER_INITIALIZED__) {\n return globalThis.__DEGEL_LOGGER__;\n }\n\n if (typeof window !== 'undefined') {\n globalThis.__DEGEL_LOGGER__ = createClientLogger(config);\n } else {\n globalThis.__DEGEL_LOGGER__ = await createServerLogger(config);\n }\n globalThis.__DEGEL_LOGGER_INITIALIZED__ = true;\n return globalThis.__DEGEL_LOGGER__;\n}\n\n/**\n * 共通ロガーオブジェクト(後方互換性のため)\n * サーバー/クライアントで自動的に適切なロガーを選択\n */\nexport const logger: Logger = {\n debug: (ctxOrMessage, messageOrLocation, originalError) =>\n getLogger().debug(ctxOrMessage as string, messageOrLocation, originalError),\n info: (ctxOrMessage, messageOrLocation, originalError) =>\n getLogger().info(ctxOrMessage as string, messageOrLocation, originalError),\n warn: (ctxOrMessage, messageOrLocation, originalError) =>\n getLogger().warn(ctxOrMessage as string, messageOrLocation, originalError),\n error: (ctxOrMessage, messageOrLocation, originalError) =>\n getLogger().error(\n ctxOrMessage as string,\n messageOrLocation,\n originalError as Error | string | null | undefined\n ),\n fatal: (ctxOrMessage, messageOrLocation, originalError) =>\n getLogger().fatal(\n ctxOrMessage as string,\n messageOrLocation,\n originalError as Error | string | null | undefined\n ),\n sqlError: (message, location, originalError) =>\n getLogger().sqlError(message, location, originalError),\n} as Logger;\n\nexport default logger;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { LOG_LEVEL_PRIORITY, VALID_LOG_LEVELS } from './constants.js';\nimport type { LogContext, LogLevel, Logger, LoggerConfig } from './types.js';\nimport { formatLogMessage, formatLogMessageWithContext, isLogContext } from './utils.js';\n\n/**\n * 指定されたログレベルが最小レベル以上かどうかを判定\n */\nfunction shouldLog(logLevel: LogLevel, minLevel: LogLevel): boolean {\n return LOG_LEVEL_PRIORITY[logLevel] >= LOG_LEVEL_PRIORITY[minLevel];\n}\n\n/**\n * クライアントサイド用ロガーを作成\n */\nexport function createClientLogger(config: LoggerConfig = {}): Logger {\n const { timezoneOffset = 540, enableConsole = true, level = 'debug' } = config;\n\n // 有効なログレベルかどうかを検証\n const minLevel: LogLevel = VALID_LOG_LEVELS.includes(level) ? level : 'debug';\n\n const logToConsole = (\n logLevel: LogLevel,\n displayLevel: string,\n consoleMethod: (...args: unknown[]) => void,\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n errorOrOriginal?: unknown\n ): void => {\n if (!enableConsole) return;\n if (!shouldLog(logLevel, minLevel)) return;\n\n let formattedMessage: string;\n\n if (isLogContext(ctxOrMessage)) {\n // 構造化コンテキスト形式: (ctx, message, error?)\n formattedMessage = formatLogMessageWithContext(\n displayLevel,\n messageOrLocation ?? '',\n ctxOrMessage,\n errorOrOriginal,\n timezoneOffset\n );\n } else {\n // レガシー形式: (message, location?, originalError?)\n formattedMessage = formatLogMessage(\n displayLevel,\n ctxOrMessage,\n (messageOrLocation as string) ?? null,\n (errorOrOriginal as Error | string) ?? null,\n timezoneOffset\n );\n }\n\n consoleMethod(formattedMessage);\n };\n\n return {\n debug: (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n originalError?: unknown\n ) => {\n logToConsole('debug', 'debug', console.debug, ctxOrMessage, messageOrLocation, originalError);\n },\n info: (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n originalError?: unknown\n ) => {\n logToConsole('info', 'info', console.info, ctxOrMessage, messageOrLocation, originalError);\n },\n warn: (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n originalError?: unknown\n ) => {\n logToConsole('warn', 'warn', console.warn, ctxOrMessage, messageOrLocation, originalError);\n },\n error: (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n originalError?: unknown\n ) => {\n logToConsole('error', 'error', console.error, ctxOrMessage, messageOrLocation, originalError);\n },\n fatal: (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n originalError?: unknown\n ) => {\n logToConsole('fatal', 'fatal', console.error, ctxOrMessage, messageOrLocation, originalError);\n },\n sqlError: (\n message: string,\n location?: string | null,\n originalError?: Error | string | null\n ) => {\n // sqlErrorはerrorレベルとしてフィルタリング、表示はsql_error\n logToConsole('error', 'sql_error', console.error, message, location, originalError);\n },\n } as Logger;\n}\n","import { createClientLogger } from './client.js';\nimport type {\n LogContext,\n LogLevel,\n LogMethod,\n LogMethodWithContext,\n LogTypeConfig,\n Logger,\n LoggerConfig,\n SentryModule,\n} from './types.js';\n\nexport type {\n LogContext,\n Logger,\n LoggerConfig,\n LogLevel,\n LogMethod,\n LogMethodWithContext,\n LogTypeConfig,\n SentryModule,\n};\n\nexport { createClientLogger };\nexport { isSentryEnabled, setSentryModule } from './sentry.js';\n\n// Constants\nexport {\n LOG_FILE_PREFIX,\n LOG_LEVEL_PRIORITY,\n LOG_ROTATION,\n TIMEZONE,\n VALID_LOG_LEVELS,\n} from './constants.js';\n\n/**\n * サーバーサイド用ロガー作成関数(動的import)\n * Next.jsなどのバンドラーでクライアント用にバンドルされる際に\n * fsモジュールの解決エラーを防ぐため、動的importで提供\n */\nexport async function createServerLogger(config?: LoggerConfig): Promise<Logger> {\n const { createServerLogger: create } = await import('./server.js');\n return create(config);\n}\n\n/**\n * グローバルシングルトン用の型定義\n * Next.js開発モードでのモジュール分離問題を解決するため、\n * globalThisを使用してロガーインスタンスを共有する\n */\ndeclare global {\n // eslint-disable-next-line no-var\n var __DEGEL_LOGGER__: Logger | undefined;\n // eslint-disable-next-line no-var\n var __DEGEL_LOGGER_INITIALIZED__: boolean | undefined;\n}\n\n/**\n * 環境を判定してデフォルトのロガーを取得\n * サーバーサイドでは非同期初期化が必要なため、初回呼び出し時はクライアントロガーを返す\n */\nexport function getLogger(): Logger {\n // グローバルに初期化済みのロガーがあれば返す\n if (globalThis.__DEGEL_LOGGER__) {\n return globalThis.__DEGEL_LOGGER__;\n }\n\n // クライアントサイドの場合\n if (typeof window !== 'undefined') {\n globalThis.__DEGEL_LOGGER__ = createClientLogger();\n return globalThis.__DEGEL_LOGGER__;\n }\n\n // サーバーサイドだが未初期化の場合は一時的にクライアントロガーを返す\n // initializeLogger()を呼び出すことで正しく初期化される\n if (!globalThis.__DEGEL_LOGGER_INITIALIZED__) {\n return createClientLogger();\n }\n\n return globalThis.__DEGEL_LOGGER__ ?? createClientLogger();\n}\n\n/**\n * サーバーサイド用の非同期初期化\n * Next.js等で使用する場合、アプリケーション起動時に呼び出す\n */\nexport async function initializeLogger(config?: LoggerConfig): Promise<Logger> {\n // 既に初期化済みの場合は既存のロガーを返す\n if (globalThis.__DEGEL_LOGGER__ && globalThis.__DEGEL_LOGGER_INITIALIZED__) {\n return globalThis.__DEGEL_LOGGER__;\n }\n\n if (typeof window !== 'undefined') {\n globalThis.__DEGEL_LOGGER__ = createClientLogger(config);\n } else {\n globalThis.__DEGEL_LOGGER__ = await createServerLogger(config);\n }\n globalThis.__DEGEL_LOGGER_INITIALIZED__ = true;\n return globalThis.__DEGEL_LOGGER__;\n}\n\n/**\n * 共通ロガーオブジェクト(後方互換性のため)\n * サーバー/クライアントで自動的に適切なロガーを選択\n */\nexport const logger: Logger = {\n debug: (ctxOrMessage, messageOrLocation, originalError) =>\n getLogger().debug(ctxOrMessage as string, messageOrLocation, originalError),\n info: (ctxOrMessage, messageOrLocation, originalError) =>\n getLogger().info(ctxOrMessage as string, messageOrLocation, originalError),\n warn: (ctxOrMessage, messageOrLocation, originalError) =>\n getLogger().warn(ctxOrMessage as string, messageOrLocation, originalError),\n error: (ctxOrMessage, messageOrLocation, originalError) =>\n getLogger().error(\n ctxOrMessage as string,\n messageOrLocation,\n originalError as Error | string | null | undefined\n ),\n fatal: (ctxOrMessage, messageOrLocation, originalError) =>\n getLogger().fatal(\n ctxOrMessage as string,\n messageOrLocation,\n originalError as Error | string | null | undefined\n ),\n sqlError: (message, location, originalError) =>\n getLogger().sqlError(message, location, originalError),\n} as Logger;\n\nexport default logger;\n"]}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk3QE5XQOJ_cjs = require('./chunk-3QE5XQOJ.cjs');
|
|
4
|
+
var pino = require('pino');
|
|
5
|
+
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var pino__default = /*#__PURE__*/_interopDefault(pino);
|
|
9
|
+
|
|
10
|
+
function shouldLog(logLevel, minLevel) {
|
|
11
|
+
return chunk3QE5XQOJ_cjs.LOG_LEVEL_PRIORITY[logLevel] >= chunk3QE5XQOJ_cjs.LOG_LEVEL_PRIORITY[minLevel];
|
|
12
|
+
}
|
|
13
|
+
async function createServerLogger(config = {}) {
|
|
14
|
+
const {
|
|
15
|
+
// biome-ignore lint/complexity/useLiteralKeys: TypeScript requires bracket notation for process.env
|
|
16
|
+
logDir = process.env["LOG_DIR"] ?? `${process.cwd()}/logs`,
|
|
17
|
+
// biome-ignore lint/complexity/useLiteralKeys: TypeScript requires bracket notation for process.env
|
|
18
|
+
level = process.env["LOG_LEVEL"] ?? "debug",
|
|
19
|
+
timezoneOffset = chunk3QE5XQOJ_cjs.TIMEZONE.JST_OFFSET_MINUTES,
|
|
20
|
+
rotationCheckInterval = chunk3QE5XQOJ_cjs.LOG_ROTATION.DEFAULT_CHECK_INTERVAL_MS,
|
|
21
|
+
enableSentry = false
|
|
22
|
+
} = config;
|
|
23
|
+
const minLevel = chunk3QE5XQOJ_cjs.VALID_LOG_LEVELS.includes(level) ? level : "debug";
|
|
24
|
+
const fs = await import('fs');
|
|
25
|
+
const path = await import('path');
|
|
26
|
+
if (!fs.existsSync(logDir)) {
|
|
27
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
28
|
+
}
|
|
29
|
+
const logTypes = {
|
|
30
|
+
debug: { fileNamePrefix: chunk3QE5XQOJ_cjs.LOG_FILE_PREFIX.DEBUG, level: "debug" },
|
|
31
|
+
info: { fileNamePrefix: chunk3QE5XQOJ_cjs.LOG_FILE_PREFIX.INFO, level: "info" },
|
|
32
|
+
error: { fileNamePrefix: chunk3QE5XQOJ_cjs.LOG_FILE_PREFIX.ERROR, level: "error" },
|
|
33
|
+
fatal: { fileNamePrefix: chunk3QE5XQOJ_cjs.LOG_FILE_PREFIX.FATAL, level: "fatal" },
|
|
34
|
+
sqlError: { fileNamePrefix: chunk3QE5XQOJ_cjs.LOG_FILE_PREFIX.SQL_ERROR, level: "error" }
|
|
35
|
+
};
|
|
36
|
+
function createLogStream(fileNamePrefix) {
|
|
37
|
+
const dateStr = chunk3QE5XQOJ_cjs.getCurrentDate(timezoneOffset);
|
|
38
|
+
const logFilePath = path.join(logDir, `${fileNamePrefix}_${dateStr}.log`);
|
|
39
|
+
return fs.createWriteStream(logFilePath, { flags: "a" });
|
|
40
|
+
}
|
|
41
|
+
function createPinoLogger(fileNamePrefix) {
|
|
42
|
+
return pino__default.default(
|
|
43
|
+
{
|
|
44
|
+
base: null,
|
|
45
|
+
timestamp: false,
|
|
46
|
+
messageKey: "message",
|
|
47
|
+
formatters: {
|
|
48
|
+
level: () => ({}),
|
|
49
|
+
bindings: () => ({})
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
createLogStream(fileNamePrefix)
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
const state = {
|
|
56
|
+
loggers: {},
|
|
57
|
+
rotationFunction: (() => {
|
|
58
|
+
}),
|
|
59
|
+
intervalId: void 0
|
|
60
|
+
};
|
|
61
|
+
for (const [type, logConfig] of Object.entries(logTypes)) {
|
|
62
|
+
state.loggers[type] = createPinoLogger(logConfig.fileNamePrefix);
|
|
63
|
+
}
|
|
64
|
+
const checkAndRotateLogFiles = () => {
|
|
65
|
+
const currentDate = chunk3QE5XQOJ_cjs.getCurrentDate(timezoneOffset);
|
|
66
|
+
if (checkAndRotateLogFiles.lastDate !== currentDate) {
|
|
67
|
+
checkAndRotateLogFiles.lastDate = currentDate;
|
|
68
|
+
for (const [type, logConfig] of Object.entries(logTypes)) {
|
|
69
|
+
state.loggers[type] = createPinoLogger(logConfig.fileNamePrefix);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
checkAndRotateLogFiles.lastDate = chunk3QE5XQOJ_cjs.getCurrentDate(timezoneOffset);
|
|
74
|
+
state.rotationFunction = checkAndRotateLogFiles;
|
|
75
|
+
if (process.env["NODE_ENV"] !== "test") {
|
|
76
|
+
state.intervalId = setInterval(checkAndRotateLogFiles, rotationCheckInterval);
|
|
77
|
+
}
|
|
78
|
+
checkAndRotateLogFiles();
|
|
79
|
+
function formatAndLog(loggerType, logLevel, message, location, originalError) {
|
|
80
|
+
if (!shouldLog(logLevel, minLevel)) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
checkAndRotateLogFiles();
|
|
84
|
+
const formattedMessage = chunk3QE5XQOJ_cjs.formatLogMessage(
|
|
85
|
+
logLevel,
|
|
86
|
+
message,
|
|
87
|
+
location,
|
|
88
|
+
originalError,
|
|
89
|
+
timezoneOffset
|
|
90
|
+
);
|
|
91
|
+
const logger = state.loggers[loggerType];
|
|
92
|
+
if (logger) {
|
|
93
|
+
logger[logLevel](formattedMessage);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function formatAndLogWithContext(loggerType, logLevel, ctx, message, error, sendToSentry = false) {
|
|
97
|
+
if (!shouldLog(logLevel, minLevel)) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
checkAndRotateLogFiles();
|
|
101
|
+
const formattedMessage = chunk3QE5XQOJ_cjs.formatLogMessageWithContext(
|
|
102
|
+
logLevel,
|
|
103
|
+
message,
|
|
104
|
+
ctx,
|
|
105
|
+
error,
|
|
106
|
+
timezoneOffset
|
|
107
|
+
);
|
|
108
|
+
const logger = state.loggers[loggerType];
|
|
109
|
+
if (logger) {
|
|
110
|
+
logger[logLevel](formattedMessage);
|
|
111
|
+
}
|
|
112
|
+
if (sendToSentry && enableSentry && chunk3QE5XQOJ_cjs.isSentryEnabled()) {
|
|
113
|
+
chunk3QE5XQOJ_cjs.captureError(ctx, message, error);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function createLogMethod(loggerType, logLevel, sendToSentry = false) {
|
|
117
|
+
return (ctxOrMessage, messageOrLocation, errorOrOriginal) => {
|
|
118
|
+
if (chunk3QE5XQOJ_cjs.isLogContext(ctxOrMessage)) {
|
|
119
|
+
formatAndLogWithContext(
|
|
120
|
+
loggerType,
|
|
121
|
+
logLevel,
|
|
122
|
+
ctxOrMessage,
|
|
123
|
+
messageOrLocation ?? "",
|
|
124
|
+
errorOrOriginal,
|
|
125
|
+
sendToSentry
|
|
126
|
+
);
|
|
127
|
+
} else {
|
|
128
|
+
formatAndLog(
|
|
129
|
+
loggerType,
|
|
130
|
+
logLevel,
|
|
131
|
+
ctxOrMessage,
|
|
132
|
+
messageOrLocation ?? null,
|
|
133
|
+
errorOrOriginal ?? null
|
|
134
|
+
);
|
|
135
|
+
if (sendToSentry && enableSentry && chunk3QE5XQOJ_cjs.isSentryEnabled()) {
|
|
136
|
+
const ctx = messageOrLocation ? { location: messageOrLocation } : {};
|
|
137
|
+
chunk3QE5XQOJ_cjs.captureError(ctx, ctxOrMessage, errorOrOriginal);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
debug: createLogMethod("debug", "debug"),
|
|
144
|
+
info: createLogMethod("info", "info"),
|
|
145
|
+
warn: createLogMethod("info", "warn"),
|
|
146
|
+
error: createLogMethod("error", "error", true),
|
|
147
|
+
fatal: createLogMethod("fatal", "fatal", true),
|
|
148
|
+
sqlError: (message, location, originalError) => {
|
|
149
|
+
formatAndLog("sqlError", "error", message, location ?? null, originalError ?? null);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
exports.createServerLogger = createServerLogger;
|
|
155
|
+
//# sourceMappingURL=server-E7QYW63S.cjs.map
|
|
156
|
+
//# sourceMappingURL=server-E7QYW63S.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server.ts"],"names":["LOG_LEVEL_PRIORITY","TIMEZONE","LOG_ROTATION","VALID_LOG_LEVELS","LOG_FILE_PREFIX","getCurrentDate","pino","formatLogMessage","formatLogMessageWithContext","isSentryEnabled","captureError","isLogContext"],"mappings":"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","file":"server-E7QYW63S.cjs","sourcesContent":["import pino from 'pino';\nimport {\n LOG_FILE_PREFIX,\n LOG_LEVEL_PRIORITY,\n LOG_ROTATION,\n TIMEZONE,\n VALID_LOG_LEVELS,\n} from './constants.js';\nimport { captureError, isSentryEnabled } from './sentry.js';\nimport type {\n LogContext,\n LogLevel,\n LogRotationFunction,\n LogTypeConfig,\n Logger,\n LoggerConfig,\n} from './types.js';\nimport {\n formatLogMessage,\n formatLogMessageWithContext,\n getCurrentDate,\n isLogContext,\n} from './utils.js';\n\n/**\n * 指定されたログレベルが最小レベル以上かどうかを判定\n */\nfunction shouldLog(logLevel: LogLevel, minLevel: LogLevel): boolean {\n return LOG_LEVEL_PRIORITY[logLevel] >= LOG_LEVEL_PRIORITY[minLevel];\n}\n\ninterface LoggerState {\n loggers: Record<string, pino.Logger>;\n rotationFunction: LogRotationFunction;\n intervalId: ReturnType<typeof setInterval> | undefined;\n}\n\n/**\n * サーバーサイド用ロガーを作成\n */\nexport async function createServerLogger(config: LoggerConfig = {}): Promise<Logger> {\n const {\n // biome-ignore lint/complexity/useLiteralKeys: TypeScript requires bracket notation for process.env\n logDir = process.env['LOG_DIR'] ?? `${process.cwd()}/logs`,\n // biome-ignore lint/complexity/useLiteralKeys: TypeScript requires bracket notation for process.env\n level = (process.env['LOG_LEVEL'] as LogLevel) ?? 'debug',\n timezoneOffset = TIMEZONE.JST_OFFSET_MINUTES,\n rotationCheckInterval = LOG_ROTATION.DEFAULT_CHECK_INTERVAL_MS,\n enableSentry = false,\n } = config;\n\n // 有効なログレベルかどうかを検証\n const minLevel: LogLevel = VALID_LOG_LEVELS.includes(level) ? level : 'debug';\n\n const fs = await import('node:fs');\n const path = await import('node:path');\n\n // ログフォルダが存在しない場合は作成\n if (!fs.existsSync(logDir)) {\n fs.mkdirSync(logDir, { recursive: true });\n }\n\n // 各ログレベル用の設定\n const logTypes: Record<string, LogTypeConfig> = {\n debug: { fileNamePrefix: LOG_FILE_PREFIX.DEBUG, level: 'debug' },\n info: { fileNamePrefix: LOG_FILE_PREFIX.INFO, level: 'info' },\n error: { fileNamePrefix: LOG_FILE_PREFIX.ERROR, level: 'error' },\n fatal: { fileNamePrefix: LOG_FILE_PREFIX.FATAL, level: 'fatal' },\n sqlError: { fileNamePrefix: LOG_FILE_PREFIX.SQL_ERROR, level: 'error' },\n };\n\n // ログストリームの作成関数\n function createLogStream(fileNamePrefix: string): ReturnType<typeof fs.createWriteStream> {\n const dateStr = getCurrentDate(timezoneOffset);\n const logFilePath = path.join(logDir, `${fileNamePrefix}_${dateStr}.log`);\n return fs.createWriteStream(logFilePath, { flags: 'a' });\n }\n\n // ロガーを作成する関数\n function createPinoLogger(fileNamePrefix: string): pino.Logger {\n return pino(\n {\n base: null,\n timestamp: false,\n messageKey: 'message',\n formatters: {\n level: () => ({}),\n bindings: () => ({}),\n },\n },\n createLogStream(fileNamePrefix)\n );\n }\n\n // 各ロガーの作成\n const state: LoggerState = {\n loggers: {},\n rotationFunction: (() => {}) as LogRotationFunction,\n intervalId: undefined,\n };\n\n for (const [type, logConfig] of Object.entries(logTypes)) {\n state.loggers[type] = createPinoLogger(logConfig.fileNamePrefix);\n }\n\n // ログファイルを日付変更時に切り替えるための関数\n const checkAndRotateLogFiles: LogRotationFunction = () => {\n const currentDate = getCurrentDate(timezoneOffset);\n\n if (checkAndRotateLogFiles.lastDate !== currentDate) {\n checkAndRotateLogFiles.lastDate = currentDate;\n\n for (const [type, logConfig] of Object.entries(logTypes)) {\n state.loggers[type] = createPinoLogger(logConfig.fileNamePrefix);\n }\n }\n };\n\n // 初期日付設定\n checkAndRotateLogFiles.lastDate = getCurrentDate(timezoneOffset);\n state.rotationFunction = checkAndRotateLogFiles;\n\n // ログローテーションのインターバル設定(テスト環境以外)\n // biome-ignore lint/complexity/useLiteralKeys: TypeScript requires bracket notation for process.env\n if (process.env['NODE_ENV'] !== 'test') {\n state.intervalId = setInterval(checkAndRotateLogFiles, rotationCheckInterval);\n }\n\n // 起動時に一度チェック\n checkAndRotateLogFiles();\n\n // カスタムフォーマットでログを出力する関数(レガシー形式)\n function formatAndLog(\n loggerType: string,\n logLevel: pino.Level,\n message: string,\n location: string | null,\n originalError: Error | string | null\n ): void {\n // ログレベルが最小レベル未満の場合はスキップ\n if (!shouldLog(logLevel as LogLevel, minLevel)) {\n return;\n }\n\n checkAndRotateLogFiles();\n\n const formattedMessage = formatLogMessage(\n logLevel,\n message,\n location,\n originalError,\n timezoneOffset\n );\n const logger = state.loggers[loggerType];\n\n if (logger) {\n logger[logLevel](formattedMessage);\n }\n }\n\n // 構造化コンテキスト対応のログ出力関数\n function formatAndLogWithContext(\n loggerType: string,\n logLevel: pino.Level,\n ctx: LogContext,\n message: string,\n error?: unknown,\n sendToSentry = false\n ): void {\n // ログレベルが最小レベル未満の場合はスキップ\n if (!shouldLog(logLevel as LogLevel, minLevel)) {\n return;\n }\n\n checkAndRotateLogFiles();\n\n const formattedMessage = formatLogMessageWithContext(\n logLevel,\n message,\n ctx,\n error,\n timezoneOffset\n );\n const logger = state.loggers[loggerType];\n\n if (logger) {\n logger[logLevel](formattedMessage);\n }\n\n // Sentry連携\n if (sendToSentry && enableSentry && isSentryEnabled()) {\n captureError(ctx, message, error);\n }\n }\n\n // オーバーロード対応のログ関数\n function createLogMethod(loggerType: string, logLevel: pino.Level, sendToSentry = false) {\n return (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n errorOrOriginal?: unknown\n ) => {\n if (isLogContext(ctxOrMessage)) {\n // 構造化コンテキスト形式\n formatAndLogWithContext(\n loggerType,\n logLevel,\n ctxOrMessage,\n messageOrLocation ?? '',\n errorOrOriginal,\n sendToSentry\n );\n } else {\n // レガシー形式\n formatAndLog(\n loggerType,\n logLevel,\n ctxOrMessage,\n (messageOrLocation as string) ?? null,\n (errorOrOriginal as Error | string) ?? null\n );\n\n // レガシー形式でもSentry送信(error/fatalの場合)\n if (sendToSentry && enableSentry && isSentryEnabled()) {\n const ctx: LogContext = messageOrLocation ? { location: messageOrLocation } : {};\n captureError(ctx, ctxOrMessage, errorOrOriginal);\n }\n }\n };\n }\n\n return {\n debug: createLogMethod('debug', 'debug'),\n info: createLogMethod('info', 'info'),\n warn: createLogMethod('info', 'warn'),\n error: createLogMethod('error', 'error', true),\n fatal: createLogMethod('fatal', 'fatal', true),\n sqlError: (\n message: string,\n location?: string | null,\n originalError?: Error | string | null\n ) => {\n formatAndLog('sqlError', 'error', message, location ?? null, originalError ?? null);\n },\n } as Logger;\n}\n"]}
|
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import { getCurrentDate, formatLogMessage, isLogContext, isSentryEnabled, captureError, formatLogMessageWithContext } from './chunk-
|
|
1
|
+
import { TIMEZONE, LOG_ROTATION, VALID_LOG_LEVELS, LOG_FILE_PREFIX, getCurrentDate, formatLogMessage, isLogContext, isSentryEnabled, captureError, LOG_LEVEL_PRIORITY, formatLogMessageWithContext } from './chunk-B7IDJBGL.js';
|
|
2
2
|
import pino from 'pino';
|
|
3
3
|
|
|
4
|
-
var LOG_LEVEL_PRIORITY = {
|
|
5
|
-
debug: 0,
|
|
6
|
-
info: 1,
|
|
7
|
-
warn: 2,
|
|
8
|
-
error: 3,
|
|
9
|
-
fatal: 4
|
|
10
|
-
};
|
|
11
4
|
function shouldLog(logLevel, minLevel) {
|
|
12
5
|
return LOG_LEVEL_PRIORITY[logLevel] >= LOG_LEVEL_PRIORITY[minLevel];
|
|
13
6
|
}
|
|
@@ -17,24 +10,22 @@ async function createServerLogger(config = {}) {
|
|
|
17
10
|
logDir = process.env["LOG_DIR"] ?? `${process.cwd()}/logs`,
|
|
18
11
|
// biome-ignore lint/complexity/useLiteralKeys: TypeScript requires bracket notation for process.env
|
|
19
12
|
level = process.env["LOG_LEVEL"] ?? "debug",
|
|
20
|
-
timezoneOffset =
|
|
21
|
-
rotationCheckInterval =
|
|
22
|
-
// 1時間
|
|
13
|
+
timezoneOffset = TIMEZONE.JST_OFFSET_MINUTES,
|
|
14
|
+
rotationCheckInterval = LOG_ROTATION.DEFAULT_CHECK_INTERVAL_MS,
|
|
23
15
|
enableSentry = false
|
|
24
16
|
} = config;
|
|
25
|
-
const
|
|
26
|
-
const minLevel = validLevels.includes(level) ? level : "debug";
|
|
17
|
+
const minLevel = VALID_LOG_LEVELS.includes(level) ? level : "debug";
|
|
27
18
|
const fs = await import('fs');
|
|
28
19
|
const path = await import('path');
|
|
29
20
|
if (!fs.existsSync(logDir)) {
|
|
30
21
|
fs.mkdirSync(logDir, { recursive: true });
|
|
31
22
|
}
|
|
32
23
|
const logTypes = {
|
|
33
|
-
debug: { fileNamePrefix:
|
|
34
|
-
info: { fileNamePrefix:
|
|
35
|
-
error: { fileNamePrefix:
|
|
36
|
-
fatal: { fileNamePrefix:
|
|
37
|
-
sqlError: { fileNamePrefix:
|
|
24
|
+
debug: { fileNamePrefix: LOG_FILE_PREFIX.DEBUG, level: "debug" },
|
|
25
|
+
info: { fileNamePrefix: LOG_FILE_PREFIX.INFO, level: "info" },
|
|
26
|
+
error: { fileNamePrefix: LOG_FILE_PREFIX.ERROR, level: "error" },
|
|
27
|
+
fatal: { fileNamePrefix: LOG_FILE_PREFIX.FATAL, level: "fatal" },
|
|
28
|
+
sqlError: { fileNamePrefix: LOG_FILE_PREFIX.SQL_ERROR, level: "error" }
|
|
38
29
|
};
|
|
39
30
|
function createLogStream(fileNamePrefix) {
|
|
40
31
|
const dateStr = getCurrentDate(timezoneOffset);
|
|
@@ -155,5 +146,5 @@ async function createServerLogger(config = {}) {
|
|
|
155
146
|
}
|
|
156
147
|
|
|
157
148
|
export { createServerLogger };
|
|
158
|
-
//# sourceMappingURL=server-
|
|
159
|
-
//# sourceMappingURL=server-
|
|
149
|
+
//# sourceMappingURL=server-EIDMRA6K.js.map
|
|
150
|
+
//# sourceMappingURL=server-EIDMRA6K.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server.ts"],"names":[],"mappings":"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","file":"server-EIDMRA6K.js","sourcesContent":["import pino from 'pino';\nimport {\n LOG_FILE_PREFIX,\n LOG_LEVEL_PRIORITY,\n LOG_ROTATION,\n TIMEZONE,\n VALID_LOG_LEVELS,\n} from './constants.js';\nimport { captureError, isSentryEnabled } from './sentry.js';\nimport type {\n LogContext,\n LogLevel,\n LogRotationFunction,\n LogTypeConfig,\n Logger,\n LoggerConfig,\n} from './types.js';\nimport {\n formatLogMessage,\n formatLogMessageWithContext,\n getCurrentDate,\n isLogContext,\n} from './utils.js';\n\n/**\n * 指定されたログレベルが最小レベル以上かどうかを判定\n */\nfunction shouldLog(logLevel: LogLevel, minLevel: LogLevel): boolean {\n return LOG_LEVEL_PRIORITY[logLevel] >= LOG_LEVEL_PRIORITY[minLevel];\n}\n\ninterface LoggerState {\n loggers: Record<string, pino.Logger>;\n rotationFunction: LogRotationFunction;\n intervalId: ReturnType<typeof setInterval> | undefined;\n}\n\n/**\n * サーバーサイド用ロガーを作成\n */\nexport async function createServerLogger(config: LoggerConfig = {}): Promise<Logger> {\n const {\n // biome-ignore lint/complexity/useLiteralKeys: TypeScript requires bracket notation for process.env\n logDir = process.env['LOG_DIR'] ?? `${process.cwd()}/logs`,\n // biome-ignore lint/complexity/useLiteralKeys: TypeScript requires bracket notation for process.env\n level = (process.env['LOG_LEVEL'] as LogLevel) ?? 'debug',\n timezoneOffset = TIMEZONE.JST_OFFSET_MINUTES,\n rotationCheckInterval = LOG_ROTATION.DEFAULT_CHECK_INTERVAL_MS,\n enableSentry = false,\n } = config;\n\n // 有効なログレベルかどうかを検証\n const minLevel: LogLevel = VALID_LOG_LEVELS.includes(level) ? level : 'debug';\n\n const fs = await import('node:fs');\n const path = await import('node:path');\n\n // ログフォルダが存在しない場合は作成\n if (!fs.existsSync(logDir)) {\n fs.mkdirSync(logDir, { recursive: true });\n }\n\n // 各ログレベル用の設定\n const logTypes: Record<string, LogTypeConfig> = {\n debug: { fileNamePrefix: LOG_FILE_PREFIX.DEBUG, level: 'debug' },\n info: { fileNamePrefix: LOG_FILE_PREFIX.INFO, level: 'info' },\n error: { fileNamePrefix: LOG_FILE_PREFIX.ERROR, level: 'error' },\n fatal: { fileNamePrefix: LOG_FILE_PREFIX.FATAL, level: 'fatal' },\n sqlError: { fileNamePrefix: LOG_FILE_PREFIX.SQL_ERROR, level: 'error' },\n };\n\n // ログストリームの作成関数\n function createLogStream(fileNamePrefix: string): ReturnType<typeof fs.createWriteStream> {\n const dateStr = getCurrentDate(timezoneOffset);\n const logFilePath = path.join(logDir, `${fileNamePrefix}_${dateStr}.log`);\n return fs.createWriteStream(logFilePath, { flags: 'a' });\n }\n\n // ロガーを作成する関数\n function createPinoLogger(fileNamePrefix: string): pino.Logger {\n return pino(\n {\n base: null,\n timestamp: false,\n messageKey: 'message',\n formatters: {\n level: () => ({}),\n bindings: () => ({}),\n },\n },\n createLogStream(fileNamePrefix)\n );\n }\n\n // 各ロガーの作成\n const state: LoggerState = {\n loggers: {},\n rotationFunction: (() => {}) as LogRotationFunction,\n intervalId: undefined,\n };\n\n for (const [type, logConfig] of Object.entries(logTypes)) {\n state.loggers[type] = createPinoLogger(logConfig.fileNamePrefix);\n }\n\n // ログファイルを日付変更時に切り替えるための関数\n const checkAndRotateLogFiles: LogRotationFunction = () => {\n const currentDate = getCurrentDate(timezoneOffset);\n\n if (checkAndRotateLogFiles.lastDate !== currentDate) {\n checkAndRotateLogFiles.lastDate = currentDate;\n\n for (const [type, logConfig] of Object.entries(logTypes)) {\n state.loggers[type] = createPinoLogger(logConfig.fileNamePrefix);\n }\n }\n };\n\n // 初期日付設定\n checkAndRotateLogFiles.lastDate = getCurrentDate(timezoneOffset);\n state.rotationFunction = checkAndRotateLogFiles;\n\n // ログローテーションのインターバル設定(テスト環境以外)\n // biome-ignore lint/complexity/useLiteralKeys: TypeScript requires bracket notation for process.env\n if (process.env['NODE_ENV'] !== 'test') {\n state.intervalId = setInterval(checkAndRotateLogFiles, rotationCheckInterval);\n }\n\n // 起動時に一度チェック\n checkAndRotateLogFiles();\n\n // カスタムフォーマットでログを出力する関数(レガシー形式)\n function formatAndLog(\n loggerType: string,\n logLevel: pino.Level,\n message: string,\n location: string | null,\n originalError: Error | string | null\n ): void {\n // ログレベルが最小レベル未満の場合はスキップ\n if (!shouldLog(logLevel as LogLevel, minLevel)) {\n return;\n }\n\n checkAndRotateLogFiles();\n\n const formattedMessage = formatLogMessage(\n logLevel,\n message,\n location,\n originalError,\n timezoneOffset\n );\n const logger = state.loggers[loggerType];\n\n if (logger) {\n logger[logLevel](formattedMessage);\n }\n }\n\n // 構造化コンテキスト対応のログ出力関数\n function formatAndLogWithContext(\n loggerType: string,\n logLevel: pino.Level,\n ctx: LogContext,\n message: string,\n error?: unknown,\n sendToSentry = false\n ): void {\n // ログレベルが最小レベル未満の場合はスキップ\n if (!shouldLog(logLevel as LogLevel, minLevel)) {\n return;\n }\n\n checkAndRotateLogFiles();\n\n const formattedMessage = formatLogMessageWithContext(\n logLevel,\n message,\n ctx,\n error,\n timezoneOffset\n );\n const logger = state.loggers[loggerType];\n\n if (logger) {\n logger[logLevel](formattedMessage);\n }\n\n // Sentry連携\n if (sendToSentry && enableSentry && isSentryEnabled()) {\n captureError(ctx, message, error);\n }\n }\n\n // オーバーロード対応のログ関数\n function createLogMethod(loggerType: string, logLevel: pino.Level, sendToSentry = false) {\n return (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n errorOrOriginal?: unknown\n ) => {\n if (isLogContext(ctxOrMessage)) {\n // 構造化コンテキスト形式\n formatAndLogWithContext(\n loggerType,\n logLevel,\n ctxOrMessage,\n messageOrLocation ?? '',\n errorOrOriginal,\n sendToSentry\n );\n } else {\n // レガシー形式\n formatAndLog(\n loggerType,\n logLevel,\n ctxOrMessage,\n (messageOrLocation as string) ?? null,\n (errorOrOriginal as Error | string) ?? null\n );\n\n // レガシー形式でもSentry送信(error/fatalの場合)\n if (sendToSentry && enableSentry && isSentryEnabled()) {\n const ctx: LogContext = messageOrLocation ? { location: messageOrLocation } : {};\n captureError(ctx, ctxOrMessage, errorOrOriginal);\n }\n }\n };\n }\n\n return {\n debug: createLogMethod('debug', 'debug'),\n info: createLogMethod('info', 'info'),\n warn: createLogMethod('info', 'warn'),\n error: createLogMethod('error', 'error', true),\n fatal: createLogMethod('fatal', 'fatal', true),\n sqlError: (\n message: string,\n location?: string | null,\n originalError?: Error | string | null\n ) => {\n formatAndLog('sqlError', 'error', message, location ?? null, originalError ?? null);\n },\n } as Logger;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@degel_lc/logger",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "phsk関連プロジェクト共通のpino-basedロギングライブラリ",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
11
12
|
"import": "./dist/index.js",
|
|
12
|
-
"
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
13
14
|
}
|
|
14
15
|
},
|
|
15
16
|
"files": [
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/sentry.ts"],"names":[],"mappings":";AAEA,IAAM,uBAAA,GAA0B,GAAA;AAKzB,SAAS,cAAA,CAAe,iBAAiB,uBAAA,EAAiC;AAC/E,EAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AACrB,EAAA,GAAA,CAAI,QAAQ,GAAA,CAAI,OAAA,EAAQ,GAAI,cAAA,GAAiB,KAAK,GAAI,CAAA;AAEtD,EAAA,MAAM,IAAA,GAAO,IAAI,cAAA,EAAe;AAChC,EAAA,MAAM,KAAA,GAAQ,OAAO,GAAA,CAAI,WAAA,KAAgB,CAAC,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAA;AAC3D,EAAA,MAAM,GAAA,GAAM,OAAO,GAAA,CAAI,UAAA,EAAY,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAEpD,EAAA,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAK,IAAI,GAAG,CAAA,CAAA;AAChC;AAKO,SAAS,oBAAA,CAAqB,iBAAiB,uBAAA,EAAiC;AACrF,EAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AACrB,EAAA,GAAA,CAAI,QAAQ,GAAA,CAAI,OAAA,EAAQ,GAAI,cAAA,GAAiB,KAAK,GAAI,CAAA;AAEtD,EAAA,MAAM,IAAA,GAAO,IAAI,cAAA,EAAe;AAChC,EAAA,MAAM,KAAA,GAAQ,OAAO,GAAA,CAAI,WAAA,KAAgB,CAAC,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAA;AAC3D,EAAA,MAAM,GAAA,GAAM,OAAO,GAAA,CAAI,UAAA,EAAY,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AACpD,EAAA,MAAM,KAAA,GAAQ,OAAO,GAAA,CAAI,WAAA,EAAa,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AACvD,EAAA,MAAM,OAAA,GAAU,OAAO,GAAA,CAAI,aAAA,EAAe,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAC3D,EAAA,MAAM,OAAA,GAAU,OAAO,GAAA,CAAI,aAAA,EAAe,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAE3D,EAAA,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;AAC/D;AAKO,SAAS,iBACd,KAAA,EACA,OAAA,EACA,QAAA,EACA,aAAA,EACA,iBAAiB,uBAAA,EACT;AACR,EAAA,MAAM,aAAA,GAAgB,qBAAqB,cAAc,CAAA;AACzD,EAAA,MAAM,SAAA,GAAY,MAAM,WAAA,EAAY;AACpC,EAAA,MAAM,eAAe,QAAA,IAAY,SAAA;AACjC,EAAA,MAAM,WAAW,aAAA,GACb,aAAA,CAAc,UAAS,GACvB,aAAA,KAAkB,OAChB,OAAA,GACA,cAAA;AAEN,EAAA,OAAO,CAAA,EAAG,aAAa,CAAA,MAAA,EAAI,SAAS,SAAI,OAAO,CAAA,MAAA,EAAI,YAAY,CAAA,MAAA,EAAI,QAAQ,CAAA,CAAA;AAC7E;AAKO,SAAS,aAAa,GAAA,EAAiC;AAC5D,EAAA,OAAO,OAAO,GAAA,KAAQ,QAAA,IAAY,GAAA,KAAQ,IAAA,IAAQ,CAAC,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,IAAK,OAAO,GAAA,KAAQ,QAAA;AAC1F;AAKA,SAAS,cAAc,GAAA,EAAyB;AAC9C,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,IAAI,IAAI,IAAA,EAAM,KAAA,CAAM,KAAK,CAAA,KAAA,EAAQ,GAAA,CAAI,IAAI,CAAA,CAAE,CAAA;AAC3C,EAAA,IAAI,IAAI,MAAA,EAAQ,KAAA,CAAM,KAAK,CAAA,OAAA,EAAU,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AACjD,EAAA,IAAI,IAAI,MAAA,EAAQ,KAAA,CAAM,KAAK,CAAA,OAAA,EAAU,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AACjD,EAAA,IAAI,IAAI,QAAA,EAAU,KAAA,CAAM,KAAK,CAAA,SAAA,EAAY,GAAA,CAAI,QAAQ,CAAA,CAAE,CAAA;AACvD,EAAA,IAAI,IAAI,QAAA,EAAU,KAAA,CAAM,KAAK,CAAA,SAAA,EAAY,GAAA,CAAI,QAAQ,CAAA,CAAE,CAAA;AAGvD,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC9C,IAAA,IACE,CAAC,CAAC,MAAA,EAAQ,QAAA,EAAU,QAAA,EAAU,UAAA,EAAY,UAAU,CAAA,CAAE,QAAA,CAAS,GAAG,CAAA,IAClE,KAAA,KAAU,MAAA,EACV;AACA,MAAA,KAAA,CAAM,KAAK,CAAA,EAAG,GAAG,IAAI,MAAA,CAAO,KAAK,CAAC,CAAA,CAAE,CAAA;AAAA,IACtC;AAAA,EACF;AAEA,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,GAAI,CAAA,CAAA,EAAI,MAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA,GAAM,EAAA;AACtD;AAKO,SAAS,4BACd,KAAA,EACA,OAAA,EACA,GAAA,EACA,KAAA,EACA,iBAAiB,uBAAA,EACT;AACR,EAAA,MAAM,aAAA,GAAgB,qBAAqB,cAAc,CAAA;AACzD,EAAA,MAAM,SAAA,GAAY,MAAM,WAAA,EAAY;AACpC,EAAA,MAAM,WAAA,GAAc,cAAc,GAAG,CAAA;AAErC,EAAA,IAAI,SAAA,GAAY,EAAA;AAChB,EAAA,IAAI,iBAAiB,KAAA,EAAO;AAC1B,IAAA,SAAA,GAAY,CAAA,UAAA,EAAa,MAAM,OAAO,CAAA,CAAA;AACtC,IAAA,IAAI,MAAM,KAAA,EAAO;AACf,MAAA,SAAA,IAAa;AAAA,EAAK,MAAM,KAAK,CAAA,CAAA;AAAA,IAC/B;AAAA,EACF,CAAA,MAAA,IAAW,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AAChD,IAAA,SAAA,GAAY,CAAA,UAAA,EAAa,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA;AAAA,EACxC;AAEA,EAAA,MAAM,WAAA,GAAc,WAAA,GAAc,CAAA,CAAA,EAAI,WAAW,CAAA,CAAA,GAAK,EAAA;AACtD,EAAA,OAAO,CAAA,EAAG,aAAa,CAAA,MAAA,EAAI,SAAS,SAAI,OAAO,CAAA,EAAG,WAAW,CAAA,EAAG,SAAS,CAAA,CAAA;AAC3E;;;AC7GA,IAAI,YAAA,GAAoC,IAAA;AAKjC,SAAS,gBAAgB,MAAA,EAA4B;AAC1D,EAAA,YAAA,GAAe,MAAA;AACjB;AAKO,SAAS,eAAA,GAA2B;AACzC,EAAA,OAAO,YAAA,KAAiB,IAAA;AAC1B;AAYO,SAAS,YAAA,CAAa,GAAA,EAAiB,OAAA,EAAiB,KAAA,EAAuB;AACpF,EAAA,IAAI,CAAC,YAAA,EAAc;AAEnB,EAAA,IAAI,iBAAiB,KAAA,EAAO;AAC1B,IAAA,YAAA,CAAa,iBAAiB,KAAA,EAAO;AAAA,MACnC,KAAA,EAAO;AAAA,QACL,GAAG,GAAA;AAAA,QACH;AAAA;AACF,KACD,CAAA;AAAA,EACH,WAAW,KAAA,EAAO;AAChB,IAAA,YAAA,CAAa,eAAe,CAAA,EAAG,OAAO,KAAK,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA,EAAI;AAAA,MAC1D,KAAA,EAAO,OAAA;AAAA,MACP,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,EACH,CAAA,MAAO;AACL,IAAA,YAAA,CAAa,eAAe,OAAA,EAAS;AAAA,MACnC,KAAA,EAAO,OAAA;AAAA,MACP,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,EACH;AACF","file":"chunk-34MNPN6V.js","sourcesContent":["import type { LogContext } from './types.js';\n\nconst DEFAULT_TIMEZONE_OFFSET = 540; // JST = UTC+9 (in minutes)\n\n/**\n * 現在の日付を YYYY_MM_DD 形式で取得\n */\nexport function getCurrentDate(timezoneOffset = DEFAULT_TIMEZONE_OFFSET): string {\n const now = new Date();\n now.setTime(now.getTime() + timezoneOffset * 60 * 1000);\n\n const year = now.getUTCFullYear();\n const month = String(now.getUTCMonth() + 1).padStart(2, '0');\n const day = String(now.getUTCDate()).padStart(2, '0');\n\n return `${year}_${month}_${day}`;\n}\n\n/**\n * 現在の日時をフォーマットする(タイムゾーン調整付き)\n */\nexport function getFormattedDateTime(timezoneOffset = DEFAULT_TIMEZONE_OFFSET): string {\n const now = new Date();\n now.setTime(now.getTime() + timezoneOffset * 60 * 1000);\n\n const year = now.getUTCFullYear();\n const month = String(now.getUTCMonth() + 1).padStart(2, '0');\n const day = String(now.getUTCDate()).padStart(2, '0');\n const hours = String(now.getUTCHours()).padStart(2, '0');\n const minutes = String(now.getUTCMinutes()).padStart(2, '0');\n const seconds = String(now.getUTCSeconds()).padStart(2, '0');\n\n return `${year}_${month}_${day} ${hours}:${minutes}:${seconds}`;\n}\n\n/**\n * ログメッセージをフォーマットする\n */\nexport function formatLogMessage(\n level: string,\n message: string,\n location: string | null,\n originalError: Error | string | null,\n timezoneOffset = DEFAULT_TIMEZONE_OFFSET\n): string {\n const formattedDate = getFormattedDateTime(timezoneOffset);\n const errorType = level.toUpperCase();\n const locationInfo = location ?? 'Unknown';\n const original = originalError\n ? originalError.toString()\n : originalError === null\n ? message\n : 'なし';\n\n return `${formattedDate}:${errorType}:${message}:${locationInfo}:${original}`;\n}\n\n/**\n * 引数がLogContextかどうかを判定\n */\nexport function isLogContext(arg: unknown): arg is LogContext {\n return typeof arg === 'object' && arg !== null && !Array.isArray(arg) && typeof arg !== 'string';\n}\n\n/**\n * コンテキスト情報をフォーマットする\n */\nfunction formatContext(ctx: LogContext): string {\n const parts: string[] = [];\n\n if (ctx.path) parts.push(`path=${ctx.path}`);\n if (ctx.method) parts.push(`method=${ctx.method}`);\n if (ctx.userId) parts.push(`userId=${ctx.userId}`);\n if (ctx.tenantId) parts.push(`tenantId=${ctx.tenantId}`);\n if (ctx.location) parts.push(`location=${ctx.location}`);\n\n // その他のカスタムフィールド\n for (const [key, value] of Object.entries(ctx)) {\n if (\n !['path', 'method', 'userId', 'tenantId', 'location'].includes(key) &&\n value !== undefined\n ) {\n parts.push(`${key}=${String(value)}`);\n }\n }\n\n return parts.length > 0 ? `[${parts.join(', ')}]` : '';\n}\n\n/**\n * 構造化コンテキスト対応のログメッセージをフォーマットする\n */\nexport function formatLogMessageWithContext(\n level: string,\n message: string,\n ctx: LogContext,\n error: unknown,\n timezoneOffset = DEFAULT_TIMEZONE_OFFSET\n): string {\n const formattedDate = getFormattedDateTime(timezoneOffset);\n const errorType = level.toUpperCase();\n const contextInfo = formatContext(ctx);\n\n let errorInfo = '';\n if (error instanceof Error) {\n errorInfo = ` | Error: ${error.message}`;\n if (error.stack) {\n errorInfo += `\\n${error.stack}`;\n }\n } else if (error !== undefined && error !== null) {\n errorInfo = ` | Error: ${String(error)}`;\n }\n\n const contextPart = contextInfo ? ` ${contextInfo}` : '';\n return `${formattedDate}:${errorType}:${message}${contextPart}${errorInfo}`;\n}\n","/**\n * Sentry連携ヘルパー\n */\n\nimport type { LogContext, SentryModule } from './types.js';\n\nlet sentryModule: SentryModule | null = null;\n\n/**\n * Sentryモジュールを設定\n */\nexport function setSentryModule(sentry: SentryModule): void {\n sentryModule = sentry;\n}\n\n/**\n * Sentryが有効かどうか\n */\nexport function isSentryEnabled(): boolean {\n return sentryModule !== null;\n}\n\n/**\n * Sentryモジュールをクリア(テスト用)\n */\nexport function clearSentryModule(): void {\n sentryModule = null;\n}\n\n/**\n * エラーをSentryに送信\n */\nexport function captureError(ctx: LogContext, message: string, error?: unknown): void {\n if (!sentryModule) return;\n\n if (error instanceof Error) {\n sentryModule.captureException(error, {\n extra: {\n ...ctx,\n message,\n },\n });\n } else if (error) {\n sentryModule.captureMessage(`${message}: ${String(error)}`, {\n level: 'error',\n extra: ctx,\n });\n } else {\n sentryModule.captureMessage(message, {\n level: 'error',\n extra: ctx,\n });\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts"],"names":[],"mappings":"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","file":"server-J5UIJDX7.js","sourcesContent":["import pino from 'pino';\nimport { captureError, isSentryEnabled } from './sentry.js';\nimport type {\n LogContext,\n LogLevel,\n LogRotationFunction,\n LogTypeConfig,\n Logger,\n LoggerConfig,\n} from './types.js';\nimport {\n formatLogMessage,\n formatLogMessageWithContext,\n getCurrentDate,\n isLogContext,\n} from './utils.js';\n\n// ログレベルの優先度マップ\nconst LOG_LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n fatal: 4,\n};\n\n/**\n * 指定されたログレベルが最小レベル以上かどうかを判定\n */\nfunction shouldLog(logLevel: LogLevel, minLevel: LogLevel): boolean {\n return LOG_LEVEL_PRIORITY[logLevel] >= LOG_LEVEL_PRIORITY[minLevel];\n}\n\ninterface LoggerState {\n loggers: Record<string, pino.Logger>;\n rotationFunction: LogRotationFunction;\n intervalId: ReturnType<typeof setInterval> | undefined;\n}\n\n/**\n * サーバーサイド用ロガーを作成\n */\nexport async function createServerLogger(config: LoggerConfig = {}): Promise<Logger> {\n const {\n // biome-ignore lint/complexity/useLiteralKeys: TypeScript requires bracket notation for process.env\n logDir = process.env['LOG_DIR'] ?? `${process.cwd()}/logs`,\n // biome-ignore lint/complexity/useLiteralKeys: TypeScript requires bracket notation for process.env\n level = (process.env['LOG_LEVEL'] as LogLevel) ?? 'debug',\n timezoneOffset = 540,\n rotationCheckInterval = 60 * 60 * 1000, // 1時間\n enableSentry = false,\n } = config;\n\n // 有効なログレベルかどうかを検証\n const validLevels: LogLevel[] = ['debug', 'info', 'warn', 'error', 'fatal'];\n const minLevel: LogLevel = validLevels.includes(level) ? level : 'debug';\n\n const fs = await import('node:fs');\n const path = await import('node:path');\n\n // ログフォルダが存在しない場合は作成\n if (!fs.existsSync(logDir)) {\n fs.mkdirSync(logDir, { recursive: true });\n }\n\n // 各ログレベル用の設定\n const logTypes: Record<string, LogTypeConfig> = {\n debug: { fileNamePrefix: 'debug_log', level: 'debug' },\n info: { fileNamePrefix: 'info_log', level: 'info' },\n error: { fileNamePrefix: 'error_log', level: 'error' },\n fatal: { fileNamePrefix: 'fatal_log', level: 'fatal' },\n sqlError: { fileNamePrefix: 'sql_error_log', level: 'error' },\n };\n\n // ログストリームの作成関数\n function createLogStream(fileNamePrefix: string): ReturnType<typeof fs.createWriteStream> {\n const dateStr = getCurrentDate(timezoneOffset);\n const logFilePath = path.join(logDir, `${fileNamePrefix}_${dateStr}.log`);\n return fs.createWriteStream(logFilePath, { flags: 'a' });\n }\n\n // ロガーを作成する関数\n function createPinoLogger(fileNamePrefix: string): pino.Logger {\n return pino(\n {\n base: null,\n timestamp: false,\n messageKey: 'message',\n formatters: {\n level: () => ({}),\n bindings: () => ({}),\n },\n },\n createLogStream(fileNamePrefix)\n );\n }\n\n // 各ロガーの作成\n const state: LoggerState = {\n loggers: {},\n rotationFunction: (() => {}) as LogRotationFunction,\n intervalId: undefined,\n };\n\n for (const [type, logConfig] of Object.entries(logTypes)) {\n state.loggers[type] = createPinoLogger(logConfig.fileNamePrefix);\n }\n\n // ログファイルを日付変更時に切り替えるための関数\n const checkAndRotateLogFiles: LogRotationFunction = () => {\n const currentDate = getCurrentDate(timezoneOffset);\n\n if (checkAndRotateLogFiles.lastDate !== currentDate) {\n checkAndRotateLogFiles.lastDate = currentDate;\n\n for (const [type, logConfig] of Object.entries(logTypes)) {\n state.loggers[type] = createPinoLogger(logConfig.fileNamePrefix);\n }\n }\n };\n\n // 初期日付設定\n checkAndRotateLogFiles.lastDate = getCurrentDate(timezoneOffset);\n state.rotationFunction = checkAndRotateLogFiles;\n\n // ログローテーションのインターバル設定(テスト環境以外)\n // biome-ignore lint/complexity/useLiteralKeys: TypeScript requires bracket notation for process.env\n if (process.env['NODE_ENV'] !== 'test') {\n state.intervalId = setInterval(checkAndRotateLogFiles, rotationCheckInterval);\n }\n\n // 起動時に一度チェック\n checkAndRotateLogFiles();\n\n // カスタムフォーマットでログを出力する関数(レガシー形式)\n function formatAndLog(\n loggerType: string,\n logLevel: pino.Level,\n message: string,\n location: string | null,\n originalError: Error | string | null\n ): void {\n // ログレベルが最小レベル未満の場合はスキップ\n if (!shouldLog(logLevel as LogLevel, minLevel)) {\n return;\n }\n\n checkAndRotateLogFiles();\n\n const formattedMessage = formatLogMessage(\n logLevel,\n message,\n location,\n originalError,\n timezoneOffset\n );\n const logger = state.loggers[loggerType];\n\n if (logger) {\n logger[logLevel](formattedMessage);\n }\n }\n\n // 構造化コンテキスト対応のログ出力関数\n function formatAndLogWithContext(\n loggerType: string,\n logLevel: pino.Level,\n ctx: LogContext,\n message: string,\n error?: unknown,\n sendToSentry = false\n ): void {\n // ログレベルが最小レベル未満の場合はスキップ\n if (!shouldLog(logLevel as LogLevel, minLevel)) {\n return;\n }\n\n checkAndRotateLogFiles();\n\n const formattedMessage = formatLogMessageWithContext(\n logLevel,\n message,\n ctx,\n error,\n timezoneOffset\n );\n const logger = state.loggers[loggerType];\n\n if (logger) {\n logger[logLevel](formattedMessage);\n }\n\n // Sentry連携\n if (sendToSentry && enableSentry && isSentryEnabled()) {\n captureError(ctx, message, error);\n }\n }\n\n // オーバーロード対応のログ関数\n function createLogMethod(loggerType: string, logLevel: pino.Level, sendToSentry = false) {\n return (\n ctxOrMessage: LogContext | string,\n messageOrLocation?: string | null,\n errorOrOriginal?: unknown\n ) => {\n if (isLogContext(ctxOrMessage)) {\n // 構造化コンテキスト形式\n formatAndLogWithContext(\n loggerType,\n logLevel,\n ctxOrMessage,\n messageOrLocation ?? '',\n errorOrOriginal,\n sendToSentry\n );\n } else {\n // レガシー形式\n formatAndLog(\n loggerType,\n logLevel,\n ctxOrMessage,\n (messageOrLocation as string) ?? null,\n (errorOrOriginal as Error | string) ?? null\n );\n\n // レガシー形式でもSentry送信(error/fatalの場合)\n if (sendToSentry && enableSentry && isSentryEnabled()) {\n const ctx: LogContext = messageOrLocation ? { location: messageOrLocation } : {};\n captureError(ctx, ctxOrMessage, errorOrOriginal);\n }\n }\n };\n }\n\n return {\n debug: createLogMethod('debug', 'debug'),\n info: createLogMethod('info', 'info'),\n warn: createLogMethod('info', 'warn'),\n error: createLogMethod('error', 'error', true),\n fatal: createLogMethod('fatal', 'fatal', true),\n sqlError: (\n message: string,\n location?: string | null,\n originalError?: Error | string | null\n ) => {\n formatAndLog('sqlError', 'error', message, location ?? null, originalError ?? null);\n },\n } as Logger;\n}\n"]}
|