> ## Documentation Index
> Fetch the complete documentation index at: https://docs.timeback.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Observability

> Configure logging and request lifecycle hooks in the server SDK

## Logging

The SDK's built-in logger only emits warnings and errors. You can customize this with two options on `createTimeback()`:

<ParamField body="logger" type="SdkLogger">
  Custom logger instance. Compatible with console, Pino, Winston, Bunyan, and any logger whose
  methods accept a string message followed by optional arguments.
</ParamField>

<ParamField body="logLevel" type="SdkLogLevel" default="warn">
  Minimum level for the built-in logger. Ignored when a custom `logger` is provided.
</ParamField>

### Custom logger

Pass any logger whose methods accept a string message followed by optional arguments. The SDK prefixes each message with the internal scope, for example `[timeback:handlers:user]`.

<CodeGroup>
  ```typescript Pino theme={null}
  import { createTimeback } from '@timeback/sdk'
  import pino from 'pino'

  const timeback = await createTimeback({
  	logger: pino({ level: 'debug' }),
  	// ...
  })
  ```

  ```typescript Winston theme={null}
  import { createTimeback } from '@timeback/sdk'
  import winston from 'winston'

  const timeback = await createTimeback({
  	logger: winston.createLogger({
  		level: 'debug',
  		transports: [new winston.transports.Console()],
  	}),
  	// ...
  })
  ```

  ```typescript console theme={null}
  import { createTimeback } from '@timeback/sdk'

  const timeback = await createTimeback({
  	logger: console,
  	// ...
  })
  ```
</CodeGroup>

When a custom logger is provided, the SDK forwards **all** log calls to it. Level filtering is the logger's responsibility.

### Log level

When using the built-in logger, `logLevel` controls the minimum severity:

```typescript theme={null}
const timeback = await createTimeback({
	logLevel: 'debug', // 'debug' | 'info' | 'warn' | 'error' | 'silent'
	// ...
})
```

| Level    | What you see                           |
| -------- | -------------------------------------- |
| `debug`  | Everything, including request details  |
| `info`   | Operational messages and above         |
| `warn`   | Warnings and errors only **(default)** |
| `error`  | Errors only                            |
| `silent` | Nothing                                |

<Tip>
  Set the `DEBUG=1` environment variable to enable debug-level output without changing code. This
  takes effect when no explicit `logLevel` is configured.
</Tip>

## Request lifecycle hooks

Track request timing and status with the `onRequestStart` and `onRequestEnd` hooks:

```typescript theme={null}
const timeback = await createTimeback({
	hooks: {
		onRequestStart({ handler }) {
			console.log(`[${handler}] started`)
		},
		onRequestEnd({ handler, durationMs, status }) {
			console.log(`[${handler}] ${status} in ${durationMs}ms`)
		},
	},
	// ...
})
```

These fire for every SDK handler:

| Handler              | Trigger                 |
| -------------------- | ----------------------- |
| `activity.submit`    | Activity completion     |
| `activity.heartbeat` | Time-spent heartbeat    |
| `user.me`            | User profile lookup     |
| `user.verify`        | User session check      |
| `identity.signIn`    | SSO sign-in initiation  |
| `identity.callback`  | SSO callback processing |
