Skip to main content
Glama
logger.test.ts3.88 kB
/** * Tests for structured logging with correlation IDs */ import { Logger } from '../src/observability/logger.js'; import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest'; describe('Logger', () => { let logger: Logger; let consoleLogSpy: any; let consoleErrorSpy: any; let consoleWarnSpy: any; beforeEach(() => { logger = new Logger(1.0); // 100% sampling for tests consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); }); afterEach(() => { consoleLogSpy.mockRestore(); consoleErrorSpy.mockRestore(); consoleWarnSpy.mockRestore(); }); test('logs info messages with JSON structure', () => { logger.info('Test message', { key: 'value' }); expect(consoleLogSpy).toHaveBeenCalledWith( expect.stringContaining('"level":"info"') ); expect(consoleLogSpy).toHaveBeenCalledWith( expect.stringContaining('"message":"Test message"') ); expect(consoleLogSpy).toHaveBeenCalledWith( expect.stringContaining('"key":"value"') ); }); test('logs error messages with error details', () => { const error = new Error('Test error'); logger.error('Error occurred', { code: 500 }, error); expect(consoleErrorSpy).toHaveBeenCalledWith( expect.stringContaining('"level":"error"') ); expect(consoleErrorSpy).toHaveBeenCalledWith( expect.stringContaining('"message":"Error occurred"') ); expect(consoleErrorSpy).toHaveBeenCalledWith( expect.stringContaining('"name":"Error"') ); expect(consoleErrorSpy).toHaveBeenCalledWith( expect.stringContaining('"message":"Test error"') ); }); test('withCorrelation sets correlation ID in context', () => { const correlationId = 'test-correlation-123'; logger.withCorrelation(correlationId, () => { logger.info('Inside correlation context'); expect(consoleLogSpy).toHaveBeenCalledWith( expect.stringContaining(`"correlationId":"${correlationId}"`) ); }); }); test('timer decorator logs operation timing', () => { const result = logger.timer('test.operation', () => { // Simulate some work for (let i = 0; i < 1000; i++) {} return 'result'; }); expect(result).toBe('result'); expect(consoleLogSpy).toHaveBeenCalledWith( expect.stringContaining('"message":"Starting operation: test.operation"') ); expect(consoleLogSpy).toHaveBeenCalledWith( expect.stringContaining('"message":"Completed operation: test.operation"') ); }); test('timer decorator logs errors', () => { expect(() => { logger.timer('test.operation', () => { throw new Error('Operation failed'); }); }).toThrow('Operation failed'); expect(consoleErrorSpy).toHaveBeenCalledWith( expect.stringContaining('"message":"Failed operation: test.operation"') ); }); test('sampling rate controls log output', () => { const sampledLogger = new Logger(0.0); // 0% sampling sampledLogger.info('This should not be logged'); expect(consoleLogSpy).not.toHaveBeenCalled(); }); test('child logger inherits context', () => { logger.withCorrelation('parent-correlation', { userId: 'user123' }, () => { const childLogger = logger.child({ sessionId: 'session456' }); childLogger.info('Child message'); expect(consoleLogSpy).toHaveBeenCalledWith( expect.stringContaining('"correlationId":"parent-correlation"') ); expect(consoleLogSpy).toHaveBeenCalledWith( expect.stringContaining('"userId":"user123"') ); expect(consoleLogSpy).toHaveBeenCalledWith( expect.stringContaining('"sessionId":"session456"') ); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hummbl-dev/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server