import { LogLevel } from "../EnvironmentConfig";
import OneUptimeTelemetry from "./Telemetry";
import TelemetryContext from "./Telemetry/TelemetryContext";
import { SeverityNumber } from "@opentelemetry/api-logs";
import Exception from "../../Types/Exception/Exception";
import ConfigLogLevel from "../Types/ConfigLogLevel";
export function getLogAttributesFromRequest(req) {
    var _a;
    if (!req) {
        return {};
    }
    try {
        const attributes = {};
        if (req.requestId) {
            attributes.requestId = req.requestId;
        }
        if (req.tenantId) {
            attributes.projectId = req.tenantId.toString();
        }
        if ((_a = req.userAuthorization) === null || _a === void 0 ? void 0 : _a.userId) {
            attributes.userId = req.userAuthorization.userId.toString();
        }
        return attributes;
    }
    catch (_b) {
        return {};
    }
}
export default class logger {
    static getLogLevel() {
        if (!LogLevel) {
            return ConfigLogLevel.INFO;
        }
        return LogLevel;
    }
    static serializeLogBody(body) {
        if (typeof body === "string") {
            return body;
        }
        else if (body instanceof Exception || body instanceof Error) {
            return body.message;
        }
        return JSON.stringify(body);
    }
    static sanitizeAttributes(attributes) {
        if (!attributes) {
            return undefined;
        }
        try {
            const sanitized = {};
            for (const key in attributes) {
                const value = attributes[key];
                if (value !== undefined && value !== null) {
                    sanitized[key] = value;
                }
            }
            return Object.keys(sanitized).length > 0 ? sanitized : undefined;
        }
        catch (_a) {
            return undefined;
        }
    }
    static info(message, attributes) {
        const logLevel = this.getLogLevel();
        if (logLevel === ConfigLogLevel.DEBUG || logLevel === ConfigLogLevel.INFO) {
            // eslint-disable-next-line no-console
            console.info(message);
            this.emit({
                body: message,
                severityNumber: SeverityNumber.INFO,
                attributes,
            });
        }
    }
    static error(message, attributes) {
        const logLevel = this.getLogLevel();
        if (logLevel === ConfigLogLevel.DEBUG ||
            logLevel === ConfigLogLevel.INFO ||
            logLevel === ConfigLogLevel.WARN ||
            logLevel === ConfigLogLevel.ERROR) {
            // eslint-disable-next-line no-console
            console.error(message);
            this.emit({
                body: message,
                severityNumber: SeverityNumber.ERROR,
                attributes,
            });
        }
    }
    static warn(message, attributes) {
        const logLevel = this.getLogLevel();
        if (logLevel === ConfigLogLevel.DEBUG ||
            logLevel === ConfigLogLevel.INFO ||
            logLevel === ConfigLogLevel.WARN) {
            // eslint-disable-next-line no-console
            console.warn(message);
            this.emit({
                body: message,
                severityNumber: SeverityNumber.WARN,
                attributes,
            });
        }
    }
    static debug(message, attributes) {
        const logLevel = this.getLogLevel();
        if (logLevel === ConfigLogLevel.DEBUG) {
            // eslint-disable-next-line no-console
            console.debug(message);
            this.emit({
                body: message,
                severityNumber: SeverityNumber.DEBUG,
                attributes,
            });
        }
    }
    static emit(data) {
        try {
            const logger = OneUptimeTelemetry.getLogger();
            if (logger === null) {
                return;
            }
            /*
             * Merge ambient TelemetryContext attributes (projectId, userId,
             * monitorId, requestId, ...) into every log record. Attributes passed
             * explicitly to the log call take precedence over the ambient context.
             */
            const mergedAttributes = Object.assign(Object.assign({}, TelemetryContext.getAttributes()), (data.attributes || {}));
            const sanitizedAttributes = this.sanitizeAttributes(mergedAttributes);
            logger.emit(Object.assign({ body: this.serializeLogBody(data.body), severityNumber: data.severityNumber }, (sanitizedAttributes ? { attributes: sanitizedAttributes } : {})));
        }
        catch (_a) {
            // Never let logging errors propagate
        }
    }
    static trace(message, attributes) {
        const logLevel = this.getLogLevel();
        if (logLevel === ConfigLogLevel.DEBUG) {
            // eslint-disable-next-line no-console
            console.trace(message);
            this.emit({
                body: message,
                severityNumber: SeverityNumber.DEBUG,
                attributes,
            });
        }
    }
}
//# sourceMappingURL=Logger.js.map