Skip to content

Logger Usage ​

How to use @grest-ts/logger in your application.

Main features ​

  • While API of the log is simplistic, it stores additional metadata, context etc about where the log happened to help pinpoint the source when analyzing logs at scale and microservices environment.
  • Don't forget, at scale logs are not free! Log what you need, don't just "log whatever I want".

Basic Logging ​

typescript
import {GGLog} from "@grest-ts/logger"

export class MyService {
    async doSomething(request: Request): Promise<Response> {
        GGLog.debug(this, "Processing request", {requestId: request.id})

        try {
            const result = await this.process(request)
            GGLog.info(this, "Request processed", {resultId: result.id})
            return result
        } catch (error) {
            GGLog.error(this, "Failed to process", error)
            throw error
        }
    }
}

Log Levels ​

LevelMethodUse Case
DEBUGGGLog.debug()Detailed debugging info, high volume
INFOGGLog.info()Normal operations, business events
WARNGGLog.warn()Recoverable issues, degraded state
ERRORGGLog.error()Failures requiring attention
CRITICALGGLog.critical()System-level failures

Method Signatures ​

All log methods accept flexible arguments:

typescript
// Message only
GGLog.info(this, "User logged in")

// Message with data
GGLog.info(this, "User logged in", {userId, ip})

// Error only
GGLog.error(this, error)

// Message with error
GGLog.error(this, "Operation failed", error)

// Message, error, and data
GGLog.error(this, "Operation failed", error, {context: "checkout"})

Context Parameter ​

The first parameter (this or a string) identifies where the log originated:

typescript
class UserService {
    login() {
        // Logs show "UserService" as context
        GGLog.info(this, "Login attempt")
    }
}

// Or use string context
GGLog.info("Startup", "Application initialized")

Structured Data ​

Pass structured data as the last parameter:

typescript
GGLog.info(this, "Order created", {
    orderId: order.id,
    userId: user.id,
    total: order.total,
    items: order.items.length
})

Initialization ​

Logger is initialized automatically by GGRuntime. For manual setup:

typescript
import {GGLog, LogLevel} from "@grest-ts/logger"
import {GGLoggerConsole} from "@grest-ts/logger-console"

// Initialize
GGLog.init()

// Add console logger
GGLog.add(new GGLoggerConsole({
    minLevel: LogLevel.DEBUG,
    showData: true
}))

Best Practices ​

Use static and meaningful messages ​

typescript
// Good
GGLog.info(this, "Order payment processed", {orderId, amount})

// Avoid dynamic messages. At scale, these make it hard to filter for specific events.
GGLog.info(this, "Expected " + value + " to be " + somethingElse, {id: orderId})

// Avoid too generic messages, these are harder to filter later.
GGLog.info(this, "Done", {id: orderId})

Include Relevant Context ​

typescript
// Good
GGLog.error(this, "Email send failed", {
    userId,
    email: user.email,
    templateId: "welcome",
    error: error.message
})

// Avoid
GGLog.error(this, "Email failed")

Don't Log Sensitive Data ​

typescript
// Good
GGLog.info(this, "User authenticated", {userId, method: "password"})

// Avoid
GGLog.info(this, "Login", {username, password, token})

Use Appropriate Levels ​

typescript
// Debug - development details
GGLog.debug(this, "Cache lookup", {key, hit: false})

// Info - business events
GGLog.info(this, "User registered", {userId})

// Warn - recoverable issues
GGLog.warn(this, "Rate limit approaching", {userId, remaining: 5})

// Error - failures
GGLog.error(this, "Database connection failed", error)