@degel_lc/logger 0.1.0

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 ADDED
@@ -0,0 +1,222 @@
1
+ # @phsk/logger
2
+
3
+ phsk関連プロジェクト共通のpino-basedロギングライブラリ。サーバーサイド・クライアントサイド両対応。
4
+
5
+ ## インストール
6
+
7
+ ```bash
8
+ pnpm add @phsk/logger
9
+ ```
10
+
11
+ ## 使用方法
12
+
13
+ ### 基本的な使用法(レガシー形式)
14
+
15
+ ```typescript
16
+ import { logger } from '@phsk/logger';
17
+
18
+ // デバッグログ
19
+ logger.debug('デバッグ情報です', 'app.ts:10');
20
+
21
+ // 情報ログ
22
+ logger.info('ユーザーがログインしました', 'auth.ts:25');
23
+
24
+ // 警告ログ
25
+ logger.warn('注意が必要です', 'service.ts:30');
26
+
27
+ // エラーログ
28
+ try {
29
+ throw new Error('ファイルが見つかりません');
30
+ } catch (error) {
31
+ logger.error('ファイル処理中にエラー発生', 'fileHandler.ts:42', error);
32
+ }
33
+
34
+ // 致命的エラーログ
35
+ logger.fatal('アプリケーションが停止しました', 'server.ts:15', error);
36
+
37
+ // SQLエラーログ
38
+ logger.sqlError('クエリ実行に失敗', 'userModel.ts:78', error);
39
+ ```
40
+
41
+ ### 構造化コンテキスト形式
42
+
43
+ APIリクエストのコンテキスト情報を含めたログ出力が可能です。
44
+
45
+ ```typescript
46
+ import { logger } from '@phsk/logger';
47
+
48
+ // コンテキスト付きログ
49
+ logger.info({ path: '/api/users', method: 'GET', userId: 'user123' }, 'ユーザー一覧取得');
50
+
51
+ // エラーログ(コンテキスト付き)
52
+ logger.error(
53
+ { path: '/api/users', method: 'POST', userId: 'user123', tenantId: 'tenant456' },
54
+ 'ユーザー作成に失敗',
55
+ error
56
+ );
57
+
58
+ // カスタムフィールドも追加可能
59
+ logger.warn({ path: '/api/orders', orderId: 'order789' }, '在庫不足');
60
+ ```
61
+
62
+ ### サーバーサイドでの初期化(推奨)
63
+
64
+ Next.jsなどのサーバーサイドアプリケーションでは、起動時に明示的に初期化することを推奨します。
65
+
66
+ ```typescript
67
+ import { initializeLogger } from '@phsk/logger';
68
+
69
+ // アプリケーション起動時
70
+ await initializeLogger({
71
+ logDir: './logs', // ログ出力ディレクトリ
72
+ level: 'debug', // ログレベル
73
+ timezoneOffset: 540, // JST (UTC+9)
74
+ });
75
+ ```
76
+
77
+ ### カスタムロガーの作成
78
+
79
+ ```typescript
80
+ import { createClientLogger, createServerLogger } from '@phsk/logger';
81
+
82
+ // クライアント用
83
+ const clientLogger = createClientLogger({
84
+ enableConsole: true,
85
+ timezoneOffset: 540,
86
+ });
87
+
88
+ // サーバー用
89
+ const serverLogger = await createServerLogger({
90
+ logDir: './logs',
91
+ timezoneOffset: 540,
92
+ rotationCheckInterval: 3600000, // 1時間
93
+ });
94
+ ```
95
+
96
+ ## API
97
+
98
+ ### Logger インターフェース
99
+
100
+ ```typescript
101
+ interface LogContext {
102
+ path?: string; // APIパス
103
+ method?: string; // HTTPメソッド
104
+ userId?: string; // ユーザーID
105
+ tenantId?: string; // テナントID
106
+ location?: string; // ファイル位置(レガシー互換)
107
+ [key: string]: unknown; // その他の任意データ
108
+ }
109
+
110
+ interface Logger {
111
+ // 構造化コンテキスト形式
112
+ debug(ctx: LogContext, message: string): void;
113
+ info(ctx: LogContext, message: string): void;
114
+ warn(ctx: LogContext, message: string): void;
115
+ error(ctx: LogContext, message: string, error?: unknown): void;
116
+ fatal(ctx: LogContext, message: string, error?: unknown): void;
117
+
118
+ // レガシー形式
119
+ debug(message: string, location?: string | null, originalError?: Error | string | null): void;
120
+ info(message: string, location?: string | null, originalError?: Error | string | null): void;
121
+ warn(message: string, location?: string | null, originalError?: Error | string | null): void;
122
+ error(message: string, location?: string | null, originalError?: Error | string | null): void;
123
+ fatal(message: string, location?: string | null, originalError?: Error | string | null): void;
124
+ sqlError(message: string, location?: string | null, originalError?: Error | string | null): void;
125
+ }
126
+ ```
127
+
128
+ ### LoggerConfig オプション
129
+
130
+ | オプション | 型 | デフォルト | 説明 |
131
+ |-----------|-----|-----------|------|
132
+ | `logDir` | `string` | `process.cwd() + '/logs'` | ログ出力ディレクトリ(サーバーのみ) |
133
+ | `level` | `LogLevel` | `'debug'` | 最小ログレベル |
134
+ | `timezoneOffset` | `number` | `540` | タイムゾーンオフセット(分)。540 = JST |
135
+ | `rotationCheckInterval` | `number` | `3600000` | ログローテーションチェック間隔(ミリ秒) |
136
+ | `enableConsole` | `boolean` | `true` | コンソール出力の有効化(クライアントのみ) |
137
+ | `enableSentry` | `boolean` | `false` | Sentry連携の有効化(サーバーのみ) |
138
+
139
+ ### 環境変数
140
+
141
+ | 変数名 | 説明 |
142
+ |--------|------|
143
+ | `LOG_DIR` | ログ出力ディレクトリのパス |
144
+ | `LOG_LEVEL` | ログレベル(debug, info, warn, error, fatal) |
145
+
146
+ ## ログ出力形式
147
+
148
+ ```
149
+ YYYY_MM_DD HH:mm:ss:LEVEL:メッセージ:ファイル:行番号:元のエラー
150
+ ```
151
+
152
+ 例:
153
+ ```
154
+ 2026_01_17 21:30:45:ERROR:ファイル処理中にエラー発生:fileHandler.ts:42:Error: ファイルが見つかりません
155
+ ```
156
+
157
+ ## ファイル構成(サーバーサイド)
158
+
159
+ サーバーサイドでは、ログレベルごとに別ファイルに出力されます:
160
+
161
+ ```
162
+ logs/
163
+ ├── debug_log_2026_01_17.log
164
+ ├── info_log_2026_01_17.log
165
+ ├── error_log_2026_01_17.log
166
+ ├── fatal_log_2026_01_17.log
167
+ └── sql_error_log_2026_01_17.log
168
+ ```
169
+
170
+ ログファイルは日付ごとに自動ローテーションされます。
171
+
172
+ ## Sentry連携
173
+
174
+ `@sentry/node`との連携が可能です。error/fatalレベルのログを自動的にSentryに送信します。
175
+
176
+ ```typescript
177
+ import { initializeLogger, setSentryModule } from '@phsk/logger';
178
+ import * as Sentry from '@sentry/node';
179
+
180
+ // Sentryの初期化(アプリケーション側で行う)
181
+ Sentry.init({ dsn: 'your-dsn' });
182
+
183
+ // ロガーの初期化時にSentry連携を有効化
184
+ await initializeLogger({
185
+ logDir: './logs',
186
+ enableSentry: true,
187
+ });
188
+
189
+ // Sentryモジュールをインジェクト
190
+ setSentryModule(Sentry);
191
+
192
+ // error/fatalログは自動的にSentryに送信される
193
+ logger.error({ path: '/api/users' }, 'エラー発生', new Error('Something went wrong'));
194
+ ```
195
+
196
+ **注意**: `@sentry/node`はオプショナルなpeerDependencyです。Sentry連携を使用する場合は別途インストールが必要です。
197
+
198
+ ## 開発
199
+
200
+ ```bash
201
+ # 依存関係インストール
202
+ pnpm install
203
+
204
+ # 開発モード(watchモード)
205
+ pnpm dev
206
+
207
+ # ビルド
208
+ pnpm build
209
+
210
+ # テスト
211
+ pnpm test
212
+
213
+ # リント
214
+ pnpm lint:fix
215
+
216
+ # 型チェック
217
+ pnpm check
218
+ ```
219
+
220
+ ## ライセンス
221
+
222
+ MIT
@@ -0,0 +1,135 @@
1
+ import * as _sentry_node from '@sentry/node';
2
+ import { Level } from 'pino';
3
+
4
+ /**
5
+ * ログコンテキスト(構造化ログ用)
6
+ */
7
+ interface LogContext {
8
+ /** APIパス */
9
+ path?: string;
10
+ /** HTTPメソッド */
11
+ method?: string;
12
+ /** ユーザーID */
13
+ userId?: string;
14
+ /** テナントID */
15
+ tenantId?: string;
16
+ /** ファイル位置(レガシー互換) */
17
+ location?: string;
18
+ /** その他の任意データ */
19
+ [key: string]: unknown;
20
+ }
21
+ /**
22
+ * ログメソッドのシグネチャ(レガシー形式)
23
+ */
24
+ type LogMethod = (message: string, location?: string | null, originalError?: Error | string | null) => void;
25
+ /**
26
+ * ログメソッドのシグネチャ(構造化コンテキスト形式)
27
+ */
28
+ type LogMethodWithContext = (ctx: LogContext, message: string, error?: unknown) => void;
29
+ /**
30
+ * Loggerインターフェース(オーバーロード対応)
31
+ */
32
+ interface Logger {
33
+ debug(ctx: LogContext, message: string): void;
34
+ info(ctx: LogContext, message: string): void;
35
+ warn(ctx: LogContext, message: string): void;
36
+ error(ctx: LogContext, message: string, error?: unknown): void;
37
+ fatal(ctx: LogContext, message: string, error?: unknown): void;
38
+ debug(message: string, location?: string | null, originalError?: Error | string | null): void;
39
+ info(message: string, location?: string | null, originalError?: Error | string | null): void;
40
+ warn(message: string, location?: string | null, originalError?: Error | string | null): void;
41
+ error(message: string, location?: string | null, originalError?: Error | string | null): void;
42
+ fatal(message: string, location?: string | null, originalError?: Error | string | null): void;
43
+ sqlError(message: string, location?: string | null, originalError?: Error | string | null): void;
44
+ }
45
+ /**
46
+ * ログレベル
47
+ */
48
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal';
49
+ /**
50
+ * ログタイプの設定
51
+ */
52
+ interface LogTypeConfig {
53
+ fileNamePrefix: string;
54
+ level: Level;
55
+ }
56
+ /**
57
+ * Sentryモジュールの型
58
+ */
59
+ type SentryModule = typeof _sentry_node;
60
+ /**
61
+ * ロガー設定オプション
62
+ */
63
+ interface LoggerConfig {
64
+ /**
65
+ * ログ出力ディレクトリ(サーバーサイドのみ)
66
+ * デフォルト: process.cwd() + '/logs'
67
+ */
68
+ logDir?: string;
69
+ /**
70
+ * 最小ログレベル
71
+ * デフォルト: 'debug'
72
+ */
73
+ level?: LogLevel;
74
+ /**
75
+ * ログローテーションのチェック間隔(ミリ秒)
76
+ * デフォルト: 3600000 (1時間)
77
+ */
78
+ rotationCheckInterval?: number;
79
+ /**
80
+ * タイムゾーンオフセット(分)
81
+ * デフォルト: 540 (JST = UTC+9)
82
+ */
83
+ timezoneOffset?: number;
84
+ /**
85
+ * クライアントサイドでコンソール出力を有効化
86
+ * デフォルト: true
87
+ */
88
+ enableConsole?: boolean;
89
+ /**
90
+ * Sentry連携を有効化
91
+ * @default false
92
+ */
93
+ enableSentry?: boolean;
94
+ }
95
+
96
+ /**
97
+ * クライアントサイド用ロガーを作成
98
+ */
99
+ declare function createClientLogger(config?: LoggerConfig): Logger;
100
+
101
+ /**
102
+ * サーバーサイド用ロガーを作成
103
+ */
104
+ declare function createServerLogger(config?: LoggerConfig): Promise<Logger>;
105
+
106
+ /**
107
+ * Sentry連携ヘルパー
108
+ */
109
+
110
+ /**
111
+ * Sentryモジュールを設定
112
+ */
113
+ declare function setSentryModule(sentry: SentryModule): void;
114
+ /**
115
+ * Sentryが有効かどうか
116
+ */
117
+ declare function isSentryEnabled(): boolean;
118
+
119
+ /**
120
+ * 環境を判定してデフォルトのロガーを取得
121
+ * サーバーサイドでは非同期初期化が必要なため、初回呼び出し時はクライアントロガーを返す
122
+ */
123
+ declare function getLogger(): Logger;
124
+ /**
125
+ * サーバーサイド用の非同期初期化
126
+ * Next.js等で使用する場合、アプリケーション起動時に呼び出す
127
+ */
128
+ declare function initializeLogger(config?: LoggerConfig): Promise<Logger>;
129
+ /**
130
+ * 共通ロガーオブジェクト(後方互換性のため)
131
+ * サーバー/クライアントで自動的に適切なロガーを選択
132
+ */
133
+ declare const logger: Logger;
134
+
135
+ 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 };
package/dist/index.js ADDED
@@ -0,0 +1,355 @@
1
+ import pino from 'pino';
2
+
3
+ // src/utils.ts
4
+ var DEFAULT_TIMEZONE_OFFSET = 540;
5
+ function getCurrentDate(timezoneOffset = DEFAULT_TIMEZONE_OFFSET) {
6
+ const now = /* @__PURE__ */ new Date();
7
+ now.setTime(now.getTime() + timezoneOffset * 60 * 1e3);
8
+ const year = now.getUTCFullYear();
9
+ const month = String(now.getUTCMonth() + 1).padStart(2, "0");
10
+ const day = String(now.getUTCDate()).padStart(2, "0");
11
+ return `${year}_${month}_${day}`;
12
+ }
13
+ function getFormattedDateTime(timezoneOffset = DEFAULT_TIMEZONE_OFFSET) {
14
+ const now = /* @__PURE__ */ new Date();
15
+ now.setTime(now.getTime() + timezoneOffset * 60 * 1e3);
16
+ const year = now.getUTCFullYear();
17
+ const month = String(now.getUTCMonth() + 1).padStart(2, "0");
18
+ const day = String(now.getUTCDate()).padStart(2, "0");
19
+ const hours = String(now.getUTCHours()).padStart(2, "0");
20
+ const minutes = String(now.getUTCMinutes()).padStart(2, "0");
21
+ const seconds = String(now.getUTCSeconds()).padStart(2, "0");
22
+ return `${year}_${month}_${day} ${hours}:${minutes}:${seconds}`;
23
+ }
24
+ function formatLogMessage(level, message, location, originalError, timezoneOffset = DEFAULT_TIMEZONE_OFFSET) {
25
+ const formattedDate = getFormattedDateTime(timezoneOffset);
26
+ const errorType = level.toUpperCase();
27
+ const locationInfo = location ?? "Unknown";
28
+ const original = originalError ? originalError.toString() : originalError === null ? message : "\u306A\u3057";
29
+ return `${formattedDate}\uFF1A${errorType}\uFF1A${message}\uFF1A${locationInfo}\uFF1A${original}`;
30
+ }
31
+ function isLogContext(arg) {
32
+ return typeof arg === "object" && arg !== null && !Array.isArray(arg) && typeof arg !== "string";
33
+ }
34
+ function formatContext(ctx) {
35
+ const parts = [];
36
+ if (ctx.path) parts.push(`path=${ctx.path}`);
37
+ if (ctx.method) parts.push(`method=${ctx.method}`);
38
+ if (ctx.userId) parts.push(`userId=${ctx.userId}`);
39
+ if (ctx.tenantId) parts.push(`tenantId=${ctx.tenantId}`);
40
+ if (ctx.location) parts.push(`location=${ctx.location}`);
41
+ for (const [key, value] of Object.entries(ctx)) {
42
+ if (!["path", "method", "userId", "tenantId", "location"].includes(key) && value !== void 0) {
43
+ parts.push(`${key}=${String(value)}`);
44
+ }
45
+ }
46
+ return parts.length > 0 ? `[${parts.join(", ")}]` : "";
47
+ }
48
+ function formatLogMessageWithContext(level, message, ctx, error, timezoneOffset = DEFAULT_TIMEZONE_OFFSET) {
49
+ const formattedDate = getFormattedDateTime(timezoneOffset);
50
+ const errorType = level.toUpperCase();
51
+ const contextInfo = formatContext(ctx);
52
+ let errorInfo = "";
53
+ if (error instanceof Error) {
54
+ errorInfo = ` | Error: ${error.message}`;
55
+ if (error.stack) {
56
+ errorInfo += `
57
+ ${error.stack}`;
58
+ }
59
+ } else if (error !== void 0 && error !== null) {
60
+ errorInfo = ` | Error: ${String(error)}`;
61
+ }
62
+ const contextPart = contextInfo ? ` ${contextInfo}` : "";
63
+ return `${formattedDate}\uFF1A${errorType}\uFF1A${message}${contextPart}${errorInfo}`;
64
+ }
65
+
66
+ // src/client.ts
67
+ var LOG_LEVEL_PRIORITY = {
68
+ debug: 0,
69
+ info: 1,
70
+ warn: 2,
71
+ error: 3,
72
+ fatal: 4
73
+ };
74
+ function shouldLog(logLevel, minLevel) {
75
+ return LOG_LEVEL_PRIORITY[logLevel] >= LOG_LEVEL_PRIORITY[minLevel];
76
+ }
77
+ function createClientLogger(config = {}) {
78
+ const { timezoneOffset = 540, enableConsole = true, level = "debug" } = config;
79
+ const validLevels = ["debug", "info", "warn", "error", "fatal"];
80
+ const minLevel = validLevels.includes(level) ? level : "debug";
81
+ const logToConsole = (logLevel, displayLevel, consoleMethod, ctxOrMessage, messageOrLocation, errorOrOriginal) => {
82
+ if (!enableConsole) return;
83
+ if (!shouldLog(logLevel, minLevel)) return;
84
+ let formattedMessage;
85
+ if (isLogContext(ctxOrMessage)) {
86
+ formattedMessage = formatLogMessageWithContext(
87
+ displayLevel,
88
+ messageOrLocation ?? "",
89
+ ctxOrMessage,
90
+ errorOrOriginal,
91
+ timezoneOffset
92
+ );
93
+ } else {
94
+ formattedMessage = formatLogMessage(
95
+ displayLevel,
96
+ ctxOrMessage,
97
+ messageOrLocation ?? null,
98
+ errorOrOriginal ?? null,
99
+ timezoneOffset
100
+ );
101
+ }
102
+ consoleMethod(formattedMessage);
103
+ };
104
+ return {
105
+ debug: (ctxOrMessage, messageOrLocation, originalError) => {
106
+ logToConsole("debug", "debug", console.debug, ctxOrMessage, messageOrLocation, originalError);
107
+ },
108
+ info: (ctxOrMessage, messageOrLocation, originalError) => {
109
+ logToConsole("info", "info", console.info, ctxOrMessage, messageOrLocation, originalError);
110
+ },
111
+ warn: (ctxOrMessage, messageOrLocation, originalError) => {
112
+ logToConsole("warn", "warn", console.warn, ctxOrMessage, messageOrLocation, originalError);
113
+ },
114
+ error: (ctxOrMessage, messageOrLocation, originalError) => {
115
+ logToConsole("error", "error", console.error, ctxOrMessage, messageOrLocation, originalError);
116
+ },
117
+ fatal: (ctxOrMessage, messageOrLocation, originalError) => {
118
+ logToConsole("fatal", "fatal", console.error, ctxOrMessage, messageOrLocation, originalError);
119
+ },
120
+ sqlError: (message, location, originalError) => {
121
+ logToConsole("error", "sql_error", console.error, message, location, originalError);
122
+ }
123
+ };
124
+ }
125
+
126
+ // src/sentry.ts
127
+ var sentryModule = null;
128
+ function setSentryModule(sentry) {
129
+ sentryModule = sentry;
130
+ }
131
+ function isSentryEnabled() {
132
+ return sentryModule !== null;
133
+ }
134
+ function captureError(ctx, message, error) {
135
+ if (!sentryModule) return;
136
+ if (error instanceof Error) {
137
+ sentryModule.captureException(error, {
138
+ extra: {
139
+ ...ctx,
140
+ message
141
+ }
142
+ });
143
+ } else if (error) {
144
+ sentryModule.captureMessage(`${message}: ${String(error)}`, {
145
+ level: "error",
146
+ extra: ctx
147
+ });
148
+ } else {
149
+ sentryModule.captureMessage(message, {
150
+ level: "error",
151
+ extra: ctx
152
+ });
153
+ }
154
+ }
155
+
156
+ // src/server.ts
157
+ var LOG_LEVEL_PRIORITY2 = {
158
+ debug: 0,
159
+ info: 1,
160
+ warn: 2,
161
+ error: 3,
162
+ fatal: 4
163
+ };
164
+ function shouldLog2(logLevel, minLevel) {
165
+ return LOG_LEVEL_PRIORITY2[logLevel] >= LOG_LEVEL_PRIORITY2[minLevel];
166
+ }
167
+ async function createServerLogger(config = {}) {
168
+ const {
169
+ // biome-ignore lint/complexity/useLiteralKeys: TypeScript requires bracket notation for process.env
170
+ logDir = process.env["LOG_DIR"] ?? `${process.cwd()}/logs`,
171
+ // biome-ignore lint/complexity/useLiteralKeys: TypeScript requires bracket notation for process.env
172
+ level = process.env["LOG_LEVEL"] ?? "debug",
173
+ timezoneOffset = 540,
174
+ rotationCheckInterval = 60 * 60 * 1e3,
175
+ // 1時間
176
+ enableSentry = false
177
+ } = config;
178
+ const validLevels = ["debug", "info", "warn", "error", "fatal"];
179
+ const minLevel = validLevels.includes(level) ? level : "debug";
180
+ const fs = await import('fs');
181
+ const path = await import('path');
182
+ if (!fs.existsSync(logDir)) {
183
+ fs.mkdirSync(logDir, { recursive: true });
184
+ }
185
+ const logTypes = {
186
+ debug: { fileNamePrefix: "debug_log", level: "debug" },
187
+ info: { fileNamePrefix: "info_log", level: "info" },
188
+ error: { fileNamePrefix: "error_log", level: "error" },
189
+ fatal: { fileNamePrefix: "fatal_log", level: "fatal" },
190
+ sqlError: { fileNamePrefix: "sql_error_log", level: "error" }
191
+ };
192
+ function createLogStream(fileNamePrefix) {
193
+ const dateStr = getCurrentDate(timezoneOffset);
194
+ const logFilePath = path.join(logDir, `${fileNamePrefix}_${dateStr}.log`);
195
+ return fs.createWriteStream(logFilePath, { flags: "a" });
196
+ }
197
+ function createPinoLogger(fileNamePrefix) {
198
+ return pino(
199
+ {
200
+ base: null,
201
+ timestamp: false,
202
+ messageKey: "message",
203
+ formatters: {
204
+ level: () => ({}),
205
+ bindings: () => ({})
206
+ }
207
+ },
208
+ createLogStream(fileNamePrefix)
209
+ );
210
+ }
211
+ const state = {
212
+ loggers: {},
213
+ rotationFunction: (() => {
214
+ }),
215
+ intervalId: void 0
216
+ };
217
+ for (const [type, logConfig] of Object.entries(logTypes)) {
218
+ state.loggers[type] = createPinoLogger(logConfig.fileNamePrefix);
219
+ }
220
+ const checkAndRotateLogFiles = () => {
221
+ const currentDate = getCurrentDate(timezoneOffset);
222
+ if (checkAndRotateLogFiles.lastDate !== currentDate) {
223
+ checkAndRotateLogFiles.lastDate = currentDate;
224
+ for (const [type, logConfig] of Object.entries(logTypes)) {
225
+ state.loggers[type] = createPinoLogger(logConfig.fileNamePrefix);
226
+ }
227
+ }
228
+ };
229
+ checkAndRotateLogFiles.lastDate = getCurrentDate(timezoneOffset);
230
+ state.rotationFunction = checkAndRotateLogFiles;
231
+ if (process.env["NODE_ENV"] !== "test") {
232
+ state.intervalId = setInterval(checkAndRotateLogFiles, rotationCheckInterval);
233
+ }
234
+ checkAndRotateLogFiles();
235
+ function formatAndLog(loggerType, logLevel, message, location, originalError) {
236
+ if (!shouldLog2(logLevel, minLevel)) {
237
+ return;
238
+ }
239
+ checkAndRotateLogFiles();
240
+ const formattedMessage = formatLogMessage(
241
+ logLevel,
242
+ message,
243
+ location,
244
+ originalError,
245
+ timezoneOffset
246
+ );
247
+ const logger2 = state.loggers[loggerType];
248
+ if (logger2) {
249
+ logger2[logLevel](formattedMessage);
250
+ }
251
+ }
252
+ function formatAndLogWithContext(loggerType, logLevel, ctx, message, error, sendToSentry = false) {
253
+ if (!shouldLog2(logLevel, minLevel)) {
254
+ return;
255
+ }
256
+ checkAndRotateLogFiles();
257
+ const formattedMessage = formatLogMessageWithContext(
258
+ logLevel,
259
+ message,
260
+ ctx,
261
+ error,
262
+ timezoneOffset
263
+ );
264
+ const logger2 = state.loggers[loggerType];
265
+ if (logger2) {
266
+ logger2[logLevel](formattedMessage);
267
+ }
268
+ if (sendToSentry && enableSentry && isSentryEnabled()) {
269
+ captureError(ctx, message, error);
270
+ }
271
+ }
272
+ function createLogMethod(loggerType, logLevel, sendToSentry = false) {
273
+ return (ctxOrMessage, messageOrLocation, errorOrOriginal) => {
274
+ if (isLogContext(ctxOrMessage)) {
275
+ formatAndLogWithContext(
276
+ loggerType,
277
+ logLevel,
278
+ ctxOrMessage,
279
+ messageOrLocation ?? "",
280
+ errorOrOriginal,
281
+ sendToSentry
282
+ );
283
+ } else {
284
+ formatAndLog(
285
+ loggerType,
286
+ logLevel,
287
+ ctxOrMessage,
288
+ messageOrLocation ?? null,
289
+ errorOrOriginal ?? null
290
+ );
291
+ if (sendToSentry && enableSentry && isSentryEnabled()) {
292
+ const ctx = messageOrLocation ? { location: messageOrLocation } : {};
293
+ captureError(ctx, ctxOrMessage, errorOrOriginal);
294
+ }
295
+ }
296
+ };
297
+ }
298
+ return {
299
+ debug: createLogMethod("debug", "debug"),
300
+ info: createLogMethod("info", "info"),
301
+ warn: createLogMethod("info", "warn"),
302
+ error: createLogMethod("error", "error", true),
303
+ fatal: createLogMethod("fatal", "fatal", true),
304
+ sqlError: (message, location, originalError) => {
305
+ formatAndLog("sqlError", "error", message, location ?? null, originalError ?? null);
306
+ }
307
+ };
308
+ }
309
+
310
+ // src/index.ts
311
+ var defaultLogger = null;
312
+ var isInitialized = false;
313
+ function getLogger() {
314
+ if (defaultLogger) {
315
+ return defaultLogger;
316
+ }
317
+ if (typeof window !== "undefined") {
318
+ defaultLogger = createClientLogger();
319
+ return defaultLogger;
320
+ }
321
+ if (!isInitialized) {
322
+ return createClientLogger();
323
+ }
324
+ return defaultLogger ?? createClientLogger();
325
+ }
326
+ async function initializeLogger(config) {
327
+ if (typeof window !== "undefined") {
328
+ defaultLogger = createClientLogger(config);
329
+ } else {
330
+ defaultLogger = await createServerLogger(config);
331
+ }
332
+ isInitialized = true;
333
+ return defaultLogger;
334
+ }
335
+ var logger = {
336
+ debug: (ctxOrMessage, messageOrLocation, originalError) => getLogger().debug(ctxOrMessage, messageOrLocation, originalError),
337
+ info: (ctxOrMessage, messageOrLocation, originalError) => getLogger().info(ctxOrMessage, messageOrLocation, originalError),
338
+ warn: (ctxOrMessage, messageOrLocation, originalError) => getLogger().warn(ctxOrMessage, messageOrLocation, originalError),
339
+ error: (ctxOrMessage, messageOrLocation, originalError) => getLogger().error(
340
+ ctxOrMessage,
341
+ messageOrLocation,
342
+ originalError
343
+ ),
344
+ fatal: (ctxOrMessage, messageOrLocation, originalError) => getLogger().fatal(
345
+ ctxOrMessage,
346
+ messageOrLocation,
347
+ originalError
348
+ ),
349
+ sqlError: (message, location, originalError) => getLogger().sqlError(message, location, originalError)
350
+ };
351
+ var index_default = logger;
352
+
353
+ export { createClientLogger, createServerLogger, index_default as default, getLogger, initializeLogger, isSentryEnabled, logger, setSentryModule };
354
+ //# sourceMappingURL=index.js.map
355
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils.ts","../src/client.ts","../src/sentry.ts","../src/server.ts","../src/index.ts"],"names":["LOG_LEVEL_PRIORITY","shouldLog","logger"],"mappings":"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","file":"index.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","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","/**\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","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","import { createClientLogger } from './client.js';\nimport { createServerLogger } from './server.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, createServerLogger };\nexport { isSentryEnabled, setSentryModule } from './sentry.js';\n\n// デフォルトのロガーインスタンス(遅延初期化)\nlet defaultLogger: Logger | null = null;\nlet isInitialized = false;\n\n/**\n * 環境を判定してデフォルトのロガーを取得\n * サーバーサイドでは非同期初期化が必要なため、初回呼び出し時はクライアントロガーを返す\n */\nexport function getLogger(): Logger {\n if (defaultLogger) {\n return defaultLogger;\n }\n\n // クライアントサイドの場合\n if (typeof window !== 'undefined') {\n defaultLogger = createClientLogger();\n return defaultLogger;\n }\n\n // サーバーサイドだが未初期化の場合は一時的にクライアントロガーを返す\n // initializeLogger()を呼び出すことで正しく初期化される\n if (!isInitialized) {\n return createClientLogger();\n }\n\n return defaultLogger ?? createClientLogger();\n}\n\n/**\n * サーバーサイド用の非同期初期化\n * Next.js等で使用する場合、アプリケーション起動時に呼び出す\n */\nexport async function initializeLogger(config?: LoggerConfig): Promise<Logger> {\n if (typeof window !== 'undefined') {\n defaultLogger = createClientLogger(config);\n } else {\n defaultLogger = await createServerLogger(config);\n }\n isInitialized = true;\n return defaultLogger;\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/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@degel_lc/logger",
3
+ "version": "0.1.0",
4
+ "description": "phsk関連プロジェクト共通のpino-basedロギングライブラリ",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup",
20
+ "dev": "tsup --watch",
21
+ "test": "vitest run",
22
+ "test:watch": "vitest",
23
+ "lint": "biome check ./src",
24
+ "lint:fix": "biome check --write ./src",
25
+ "format": "biome format --write ./src",
26
+ "check": "pnpm lint && pnpm tsc --noEmit",
27
+ "check:fix": "pnpm lint:fix && pnpm tsc --noEmit",
28
+ "prepublishOnly": "pnpm build"
29
+ },
30
+ "keywords": [
31
+ "logger",
32
+ "pino",
33
+ "phsk",
34
+ "typescript"
35
+ ],
36
+ "author": "",
37
+ "license": "MIT",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": ""
41
+ },
42
+ "engines": {
43
+ "node": ">=18.0.0"
44
+ },
45
+ "peerDependencies": {
46
+ "pino": "^9.0.0",
47
+ "@sentry/node": "^8.0.0 || ^9.0.0"
48
+ },
49
+ "peerDependenciesMeta": {
50
+ "@sentry/node": {
51
+ "optional": true
52
+ }
53
+ },
54
+ "dependencies": {
55
+ "pino": "^9.6.0",
56
+ "pino-pretty": "^13.0.0"
57
+ },
58
+ "devDependencies": {
59
+ "@biomejs/biome": "^1.9.4",
60
+ "@sentry/node": "^9.0.0",
61
+ "@types/node": "^22.12.0",
62
+ "tsup": "^8.3.6",
63
+ "typescript": "^5.7.3",
64
+ "vitest": "^3.0.4"
65
+ },
66
+ "packageManager": "pnpm@10.26.2"
67
+ }