| const winston = require('winston') |
| const path = require('path') |
| const fs = require('fs') |
| const { maskToken } = require('./tokenMask') |
|
|
| |
| const logDir = path.join(process.cwd(), 'logs') |
| if (!fs.existsSync(logDir)) { |
| fs.mkdirSync(logDir, { recursive: true }) |
| } |
|
|
| |
| const tokenRefreshLogger = winston.createLogger({ |
| level: 'info', |
| format: winston.format.combine( |
| winston.format.timestamp({ |
| format: 'YYYY-MM-DD HH:mm:ss.SSS' |
| }), |
| winston.format.json(), |
| winston.format.printf((info) => JSON.stringify(info, null, 2)) |
| ), |
| transports: [ |
| |
| new winston.transports.File({ |
| filename: path.join(logDir, 'token-refresh.log'), |
| maxsize: 10 * 1024 * 1024, |
| maxFiles: 30, |
| tailable: true |
| }), |
| |
| new winston.transports.File({ |
| filename: path.join(logDir, 'token-refresh-error.log'), |
| level: 'error', |
| maxsize: 10 * 1024 * 1024, |
| maxFiles: 30 |
| }) |
| ], |
| |
| exitOnError: false |
| }) |
|
|
| |
| if (process.env.NODE_ENV !== 'production') { |
| tokenRefreshLogger.add( |
| new winston.transports.Console({ |
| format: winston.format.combine(winston.format.colorize(), winston.format.simple()) |
| }) |
| ) |
| } |
|
|
| |
| |
| |
| function logRefreshStart(accountId, accountName, platform = 'claude', reason = '') { |
| tokenRefreshLogger.info({ |
| event: 'token_refresh_start', |
| accountId, |
| accountName, |
| platform, |
| reason, |
| timestamp: new Date().toISOString() |
| }) |
| } |
|
|
| |
| |
| |
| function logRefreshSuccess(accountId, accountName, platform = 'claude', tokenData = {}) { |
| const maskedTokenData = { |
| accessToken: tokenData.accessToken ? maskToken(tokenData.accessToken) : '[NOT_PROVIDED]', |
| refreshToken: tokenData.refreshToken ? maskToken(tokenData.refreshToken) : '[NOT_PROVIDED]', |
| expiresAt: tokenData.expiresAt || tokenData.expiry_date || '[NOT_PROVIDED]', |
| scopes: tokenData.scopes || tokenData.scope || '[NOT_PROVIDED]' |
| } |
|
|
| tokenRefreshLogger.info({ |
| event: 'token_refresh_success', |
| accountId, |
| accountName, |
| platform, |
| tokenData: maskedTokenData, |
| timestamp: new Date().toISOString() |
| }) |
| } |
|
|
| |
| |
| |
| function logRefreshError(accountId, accountName, platform = 'claude', error, attemptNumber = 1) { |
| const errorInfo = { |
| message: error.message || error.toString(), |
| code: error.code || 'UNKNOWN', |
| statusCode: error.response?.status || 'N/A', |
| responseData: error.response?.data || 'N/A' |
| } |
|
|
| tokenRefreshLogger.error({ |
| event: 'token_refresh_error', |
| accountId, |
| accountName, |
| platform, |
| error: errorInfo, |
| attemptNumber, |
| timestamp: new Date().toISOString() |
| }) |
| } |
|
|
| |
| |
| |
| function logRefreshSkipped(accountId, accountName, platform = 'claude', reason = 'locked') { |
| tokenRefreshLogger.info({ |
| event: 'token_refresh_skipped', |
| accountId, |
| accountName, |
| platform, |
| reason, |
| timestamp: new Date().toISOString() |
| }) |
| } |
|
|
| |
| |
| |
| function logTokenUsage(accountId, accountName, platform = 'claude', expiresAt, isExpired) { |
| tokenRefreshLogger.debug({ |
| event: 'token_usage_check', |
| accountId, |
| accountName, |
| platform, |
| expiresAt, |
| isExpired, |
| remainingMinutes: expiresAt ? Math.floor((new Date(expiresAt) - Date.now()) / 60000) : 'N/A', |
| timestamp: new Date().toISOString() |
| }) |
| } |
|
|
| |
| |
| |
| function logBatchRefreshStart(totalAccounts, platform = 'all') { |
| tokenRefreshLogger.info({ |
| event: 'batch_refresh_start', |
| totalAccounts, |
| platform, |
| timestamp: new Date().toISOString() |
| }) |
| } |
|
|
| |
| |
| |
| function logBatchRefreshComplete(results) { |
| tokenRefreshLogger.info({ |
| event: 'batch_refresh_complete', |
| results: { |
| total: results.total || 0, |
| success: results.success || 0, |
| failed: results.failed || 0, |
| skipped: results.skipped || 0 |
| }, |
| timestamp: new Date().toISOString() |
| }) |
| } |
|
|
| module.exports = { |
| logger: tokenRefreshLogger, |
| logRefreshStart, |
| logRefreshSuccess, |
| logRefreshError, |
| logRefreshSkipped, |
| logTokenUsage, |
| logBatchRefreshStart, |
| logBatchRefreshComplete |
| } |
|
|