@gftdcojp/gftd-orm
Version:
Enterprise-grade real-time data platform with ksqlDB, inspired by Supabase architecture
293 lines • 8.13 kB
JavaScript
/**
* クライアントサイド専用ログ機能
* winston を使わず console ベースで実装
*/
import { isBrowser } from './utils/env';
/**
* デフォルト設定
*/
const defaultConfig = {
level: 'info',
enableTimestamp: true,
enableColors: true,
enableStackTrace: false,
prefix: '[GFTD-ORM]',
};
/**
* ログレベルの順序
*/
const logLevels = {
debug: 0,
info: 1,
warn: 2,
error: 3,
};
/**
* ログ色
*/
const logColors = {
debug: '#6B7280', // gray
info: '#3B82F6', // blue
warn: '#F59E0B', // amber
error: '#EF4444', // red
};
/**
* ログ絵文字
*/
const logEmojis = {
debug: '🐛',
info: 'ℹ️',
warn: '⚠️',
error: '❌',
};
/**
* クライアント用ログ機能
*/
export class ClientLogger {
constructor(config = {}) {
this.config = { ...defaultConfig, ...config };
// ブラウザ環境でのみ動作
if (!isBrowser()) {
throw new Error('ClientLogger can only be used in browser environment');
}
}
/**
* シングルトンインスタンスを取得
*/
static getInstance(config) {
if (!ClientLogger.instance) {
ClientLogger.instance = new ClientLogger(config);
}
return ClientLogger.instance;
}
/**
* 設定を更新
*/
setConfig(config) {
this.config = { ...this.config, ...config };
}
/**
* ログレベルを設定
*/
setLevel(level) {
this.config.level = level;
}
/**
* ログを出力するかどうかを判定
*/
shouldLog(level) {
return logLevels[level] >= logLevels[this.config.level];
}
/**
* タイムスタンプを取得
*/
getTimestamp() {
if (!this.config.enableTimestamp)
return '';
return new Date().toISOString();
}
/**
* フォーマットされたメッセージを作成
*/
formatMessage(level, message, meta) {
const timestamp = this.getTimestamp();
const prefix = this.config.prefix || '';
const emoji = logEmojis[level];
let formattedMessage = '';
if (timestamp) {
formattedMessage += `[${timestamp}] `;
}
if (prefix) {
formattedMessage += `${prefix} `;
}
formattedMessage += `${emoji} ${message}`;
if (meta && Object.keys(meta).length > 0) {
formattedMessage += ` ${JSON.stringify(meta)}`;
}
return formattedMessage;
}
/**
* ログを出力
*/
log(level, message, meta) {
if (!this.shouldLog(level))
return;
const formattedMessage = this.formatMessage(level, message, meta);
// コンソールのスタイル設定
if (this.config.enableColors && typeof console !== 'undefined') {
const color = logColors[level];
const style = `color: ${color}; font-weight: bold;`;
switch (level) {
case 'debug':
console.debug(`%c${formattedMessage}`, style);
break;
case 'info':
console.info(`%c${formattedMessage}`, style);
break;
case 'warn':
console.warn(`%c${formattedMessage}`, style);
break;
case 'error':
console.error(`%c${formattedMessage}`, style);
break;
}
}
else {
// 色なしの場合
switch (level) {
case 'debug':
console.debug(formattedMessage);
break;
case 'info':
console.info(formattedMessage);
break;
case 'warn':
console.warn(formattedMessage);
break;
case 'error':
console.error(formattedMessage);
break;
}
}
}
/**
* デバッグログ
*/
debug(message, meta) {
this.log('debug', message, meta);
}
/**
* 情報ログ
*/
info(message, meta) {
this.log('info', message, meta);
}
/**
* 警告ログ
*/
warn(message, meta) {
this.log('warn', message, meta);
}
/**
* エラーログ
*/
error(message, error, meta) {
let errorMeta = meta || {};
if (error instanceof Error) {
errorMeta = {
...errorMeta,
error: error.message,
stack: this.config.enableStackTrace ? error.stack : undefined,
};
}
else if (error) {
errorMeta = {
...errorMeta,
error: error,
};
}
this.log('error', message, errorMeta);
}
/**
* 成功ログ
*/
success(message, meta) {
this.info(`✅ ${message}`, meta);
}
/**
* 失敗ログ
*/
failure(message, error, meta) {
this.error(`❌ ${message}`, error, meta);
}
/**
* グループ化されたログ
*/
group(label) {
if (console.group) {
console.group(`🔍 ${label}`);
}
}
/**
* グループ終了
*/
groupEnd() {
if (console.groupEnd) {
console.groupEnd();
}
}
/**
* テーブル形式のログ
*/
table(data) {
if (console.table) {
console.table(data);
}
else {
this.info('Table data:', data);
}
}
/**
* 時間計測開始
*/
time(label) {
if (console.time) {
console.time(label);
}
}
/**
* 時間計測終了
*/
timeEnd(label) {
if (console.timeEnd) {
console.timeEnd(label);
}
}
}
// デフォルトのログ機能をエクスポート
let _clientLog = null;
export const clientLog = {
get instance() {
if (!_clientLog) {
_clientLog = ClientLogger.getInstance();
}
return _clientLog;
},
debug: (message, meta) => clientLog.instance.debug(message, meta),
info: (message, meta) => clientLog.instance.info(message, meta),
warn: (message, meta) => clientLog.instance.warn(message, meta),
error: (message, error, meta) => clientLog.instance.error(message, error, meta),
success: (message, meta) => clientLog.instance.success(message, meta),
failure: (message, error, meta) => clientLog.instance.failure(message, error, meta),
group: (label) => clientLog.instance.group(label),
groupEnd: () => clientLog.instance.groupEnd(),
table: (data) => clientLog.instance.table(data),
time: (label) => clientLog.instance.time(label),
timeEnd: (label) => clientLog.instance.timeEnd(label),
setLevel: (level) => clientLog.instance.setLevel(level),
setConfig: (config) => clientLog.instance.setConfig(config),
};
/**
* ログ設定を初期化
*/
export function initializeClientLogger(config = {}) {
return ClientLogger.getInstance(config);
}
/**
* 従来のコンソールログ代替機能
*/
export const consoleLogger = {
debug: (message, ...args) => clientLog.debug(message, { args }),
info: (message, ...args) => clientLog.info(message, { args }),
warn: (message, ...args) => clientLog.warn(message, { args }),
error: (message, ...args) => clientLog.error(message, args[0], { args: args.slice(1) }),
log: (message, ...args) => clientLog.info(message, { args }),
success: (message, ...args) => clientLog.success(message, { args }),
failure: (message, error, ...args) => clientLog.failure(message, error, { args }),
group: (label) => clientLog.group(label),
groupEnd: () => clientLog.groupEnd(),
table: (data) => clientLog.table(data),
time: (label) => clientLog.time(label),
timeEnd: (label) => clientLog.timeEnd(label),
};
//# sourceMappingURL=client-logger.js.map