Documentation Index Fetch the complete documentation index at: https://mintlify.com/iii-hq/sdk/llms.txt
Use this file to discover all available pages before exploring further.
Every III function handler has access to a context object that provides logging, tracing, and request metadata.
getContext()
Get the current context within a function handler.
import { getContext } from 'iii-sdk'
const context = getContext ()
Current execution context Logger instance for structured logging
Active OpenTelemetry span for custom tracing (undefined if OTel is disabled)
Example: Basic Usage
import { init , getContext } from 'iii-sdk'
const iii = init ( 'ws://localhost:49199' )
iii . registerFunction (
{ id: 'users::create' },
async ( data : { email : string ; name : string }) => {
const { logger , trace } = getContext ()
// Log with structured data
logger . info ( 'Creating user' , { email: data . email })
// Add trace attributes
trace ?. setAttribute ( 'user.email' , data . email )
const user = {
id: crypto . randomUUID (),
email: data . email ,
name: data . name ,
created_at: new Date (). toISOString ()
}
logger . info ( 'User created' , { userId: user . id })
trace ?. addEvent ( 'User created successfully' )
return user
}
)
Logger
The Logger provides structured logging with automatic trace correlation.
Methods
info()
Log an informational message.
logger . info ( message , data ? )
Optional structured data to include in the log
warn()
Log a warning message.
logger . warn ( message , data ? )
error()
Log an error message.
logger . error ( message , data ? )
Optional error details or structured data
debug()
Log a debug message.
logger . debug ( message , data ? )
Example: Structured Logging
import { init , getContext } from 'iii-sdk'
const iii = init ( 'ws://localhost:49199' )
iii . registerFunction (
{ id: 'orders::process' },
async ( data : { order_id : string ; items : any [] }) => {
const { logger } = getContext ()
logger . info ( 'Processing order' , {
order_id: data . order_id ,
item_count: data . items . length
})
try {
// Validate order
if ( data . items . length === 0 ) {
logger . warn ( 'Order has no items' , { order_id: data . order_id })
throw new Error ( 'Order must contain at least one item' )
}
// Process items
for ( const item of data . items ) {
logger . debug ( 'Processing item' , {
order_id: data . order_id ,
item_id: item . id ,
quantity: item . quantity
})
}
logger . info ( 'Order processed successfully' , {
order_id: data . order_id
})
return { success: true , order_id: data . order_id }
} catch ( error ) {
logger . error ( 'Failed to process order' , {
order_id: data . order_id ,
error: error . message
})
throw error
}
}
)
Automatic Trace Correlation
Logs are automatically correlated with traces:
import { init , getContext } from 'iii-sdk'
const iii = init ( 'ws://localhost:49199' )
iii . registerFunction (
{ id: 'service_a::handler' },
async ( data ) => {
const { logger } = getContext ()
logger . info ( 'Service A: Processing request' )
// Log includes trace_id and span_id automatically
// Call another service
const result = await iii . call ( 'service_b::handler' , data )
logger . info ( 'Service A: Received response from B' )
return result
}
)
iii . registerFunction (
{ id: 'service_b::handler' },
async ( data ) => {
const { logger } = getContext ()
logger . info ( 'Service B: Processing request' )
// This log has the same trace_id, allowing correlation
return { processed: true }
}
)
All logs from both services share the same trace_id, making it easy to trace requests across services.
Trace Span
The trace span allows adding custom attributes, events, and status to the current trace.
setAttribute()
Add a custom attribute to the span.
trace ?. setAttribute ( key , value )
value
string | number | boolean
required
Attribute value
addEvent()
Add a timestamped event to the span.
trace ?. addEvent ( name , attributes ? )
Optional event attributes
setStatus()
Set the span status.
import { SpanStatusCode } from 'iii-sdk/telemetry'
trace ?. setStatus ({ code: SpanStatusCode . ERROR , message: 'Operation failed' })
recordException()
Record an exception in the span.
try {
// risky operation
} catch ( error ) {
trace ?. recordException ( error as Error )
throw error
}
Example: Rich Tracing
import { init , getContext } from 'iii-sdk'
import { SpanStatusCode } from 'iii-sdk/telemetry'
const iii = init ( 'ws://localhost:49199' )
iii . registerFunction (
{ id: 'payments::process' },
async ( data : { amount : number ; currency : string ; user_id : string }) => {
const { logger , trace } = getContext ()
// Add attributes
trace ?. setAttribute ( 'payment.amount' , data . amount )
trace ?. setAttribute ( 'payment.currency' , data . currency )
trace ?. setAttribute ( 'user.id' , data . user_id )
try {
// Step 1: Validate
trace ?. addEvent ( 'Validating payment details' )
await validatePayment ( data )
// Step 2: Charge
trace ?. addEvent ( 'Charging payment' , {
'payment.method' : 'stripe'
})
const charge = await chargePayment ( data )
trace ?. setAttribute ( 'payment.charge_id' , charge . id )
trace ?. setAttribute ( 'payment.status' , 'succeeded' )
// Step 3: Record
trace ?. addEvent ( 'Recording transaction' )
await recordTransaction ( charge )
logger . info ( 'Payment processed' , {
charge_id: charge . id ,
amount: data . amount
})
trace ?. setStatus ({ code: SpanStatusCode . OK })
return {
success: true ,
charge_id: charge . id
}
} catch ( error ) {
// Record the exception in the trace
trace ?. recordException ( error as Error )
trace ?. setStatus ({
code: SpanStatusCode . ERROR ,
message: error . message
})
logger . error ( 'Payment failed' , {
error: error . message ,
user_id: data . user_id
})
throw error
}
}
)
withContext()
Manually set context for async operations (advanced use case).
import { withContext } from 'iii-sdk'
await withContext ( fn , context )
fn
(context: Context) => Promise<T>
required
Async function to execute with the context
The function’s return value
You typically don’t need to use withContext() directly. The III SDK manages context automatically for function handlers.
Example: Custom Context
import { withContext , Logger } from 'iii-sdk'
// Create a custom logger
const customLogger = new Logger ( 'custom-trace-id' , 'my-service' )
// Run code with custom context
await withContext (
async ( ctx ) => {
ctx . logger . info ( 'Using custom context' )
// Your code here
},
{ logger: customLogger }
)
Logger Constructor
Create a standalone logger instance outside of function handlers.
import { Logger } from 'iii-sdk'
const logger = new Logger ( traceId ? , serviceName ? , spanId ? )
Optional trace ID for correlation
Example: Standalone Logger
import { Logger } from 'iii-sdk'
// Logger without trace context
const logger = new Logger ()
logger . info ( 'Application starting' )
// Logger with trace ID
const traceLogger = new Logger ( 'abc123' , 'my-service' )
traceLogger . info ( 'Processing request' , { request_id: '456' })
Best Practices
Always use structured logging
// Good - structured data
logger . info ( 'User created' , { userId: user . id , email: user . email })
// Avoid - string interpolation
logger . info ( `User ${ user . id } created with email ${ user . email } ` )
Add meaningful trace attributes
const { trace } = getContext ()
// Business context
trace ?. setAttribute ( 'order.id' , order . id )
trace ?. setAttribute ( 'order.total' , order . total )
trace ?. setAttribute ( 'user.tier' , user . tier )
// Technical context
trace ?. setAttribute ( 'db.query_count' , queries . length )
trace ?. setAttribute ( 'cache.hit' , true )
Use appropriate log levels
// debug: Detailed information for debugging
logger . debug ( 'Cache miss' , { key })
// info: General informational messages
logger . info ( 'User logged in' , { userId })
// warn: Warning messages for recoverable issues
logger . warn ( 'Rate limit approaching' , { current , limit })
// error: Error messages for failures
logger . error ( 'Payment failed' , { error: err . message })
Add events for important milestones
const { trace } = getContext ()
trace ?. addEvent ( 'Order validated' )
// ... validation logic
trace ?. addEvent ( 'Payment processed' , {
'payment.method' : 'card' ,
'payment.amount' : amount
})
// ... payment logic
trace ?. addEvent ( 'Order completed' )
Handle errors with trace context
try {
await riskyOperation ()
} catch ( error ) {
const { logger , trace } = getContext ()
// Log the error
logger . error ( 'Operation failed' , {
error: error . message ,
stack: error . stack
})
// Record in trace
trace ?. recordException ( error as Error )
trace ?. setStatus ({
code: SpanStatusCode . ERROR ,
message: error . message
})
throw error
}
Context Outside Handlers
If you call getContext() outside a function handler, you get a default context with a basic logger:
import { getContext } from 'iii-sdk'
// Outside any function handler
const { logger } = getContext ()
logger . info ( 'Application initialized' ) // Works, but no trace correlation
// Inside a function handler
iii . registerFunction ({ id: 'fn' }, async ( data ) => {
const { logger , trace } = getContext ()
// Now logger has trace context and trace is available
})