proxy-connection
Version:
Proxy client with automatic connection management, health checking, and fetch-like API
162 lines • 4.93 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.NullLogger = exports.FileLogger = void 0;
const fs_1 = require("fs");
const fs_2 = require("fs");
const path_1 = require("path");
class FileLogger {
logsDir;
logFile;
user = null;
tags = {};
extras = {};
contexts = {};
breadcrumbs = [];
maxLogFileSize = 5 * 1024 * 1024; // 5 MB
constructor(logsDir = './logs') {
this.logsDir = logsDir;
this.logFile = (0, path_1.join)(logsDir, 'app.log');
this.ensureLogDir();
}
ensureLogDir() {
try {
if (!(0, fs_1.existsSync)(this.logsDir)) {
(0, fs_1.mkdirSync)(this.logsDir, { recursive: true });
}
}
catch (error) {
console.error('Failed to create logs directory:', error);
}
}
formatLogEntry(level, message, data) {
const timestamp = new Date().toISOString();
const logEntry = {
timestamp,
level,
message,
user: this.user,
tags: Object.keys(this.tags).length > 0 ? this.tags : undefined,
extras: Object.keys(this.extras).length > 0 ? this.extras : undefined,
contexts: Object.keys(this.contexts).length > 0 ? this.contexts : undefined,
breadcrumbs: this.breadcrumbs.length > 0 ? this.breadcrumbs.slice(-10) : undefined, // Keep last 10 breadcrumbs
data
};
return JSON.stringify(logEntry, null, 2) + '\n---\n';
}
async rotateLogFile() {
const stats = (0, fs_1.existsSync)(this.logFile) ? await fs_2.promises.stat(this.logFile) : null;
if (stats && stats.size > this.maxLogFileSize) {
const rotatedFile = `${this.logFile}.${new Date().toISOString().replace(/[:.]/g, '-')}`;
await fs_2.promises.rename(this.logFile, rotatedFile);
}
}
async writeLogAsync(logEntry) {
try {
await this.rotateLogFile();
await fs_2.promises.appendFile(this.logFile, logEntry);
}
catch (writeError) {
console.error('Failed to write to log file:', writeError);
}
}
async captureException(exception, _hint, _context) {
const errorData = {
name: exception?.name || 'Unknown',
message: exception?.message || String(exception),
stack: exception?.stack || 'No stack trace available',
context: _context
};
const logEntry = this.formatLogEntry('error', `Exception: ${exception?.message || String(exception)}`, errorData);
await this.writeLogAsync(logEntry);
return this.generateEventId();
}
async captureMessage(message, level = 'info', _hint, _context) {
const logEntry = this.formatLogEntry(level, message);
await this.writeLogAsync(logEntry);
return this.generateEventId();
}
setUser(user) {
this.user = user;
}
setTag(key, value) {
this.tags[key] = value;
}
setTags(tags) {
this.tags = { ...this.tags, ...tags };
}
setExtra(key, value) {
this.extras[key] = value;
}
setExtras(extras) {
this.extras = { ...this.extras, ...extras };
}
setContext(name, context) {
this.contexts[name] = context;
}
addBreadcrumb(breadcrumb) {
this.breadcrumbs.push({
...breadcrumb,
timestamp: Math.floor(Date.now() / 1000)
});
if (this.breadcrumbs.length > 100) {
this.breadcrumbs = this.breadcrumbs.slice(-100);
}
}
withScope(callback) {
callback({});
}
generateEventId() {
return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
}
async info(message, _data) {
return this.captureMessage(message, 'info');
}
async warn(message, _data) {
return this.captureMessage(message, 'warning');
}
async error(message, _data) {
return this.captureMessage(message, 'error');
}
async debug(message, _data) {
return this.captureMessage(message, 'debug');
}
async fatal(message, _data) {
return this.captureMessage(message, 'fatal');
}
}
exports.FileLogger = FileLogger;
// Null Object Pattern - логгер который ничего не делает
class NullLogger {
async captureException() {
return '';
}
async captureMessage() {
return '';
}
setUser() {
// no-op
}
setTag() {
// no-op
}
setTags() {
// no-op
}
setExtra() {
// no-op
}
setExtras() {
// no-op
}
setContext() {
// no-op
}
addBreadcrumb() {
// no-op
}
withScope() {
// no-op
}
}
exports.NullLogger = NullLogger;
//# sourceMappingURL=index.js.map