Kotlin SDK
GitHubOfficial Kotlin SDK for LogWard with coroutines support, automatic batching, retry logic, circuit breaker, query API, and middleware integrations for Ktor, Spring Boot, and Jakarta Servlet.
Installation
Gradle (Kotlin DSL)
kotlin
dependencies {
implementation("io.github.logward-dev:logward-sdk-kotlin:0.2.0")
}Gradle (Groovy)
groovy
dependencies {
implementation 'io.github.logward-dev:logward-sdk-kotlin:0.2.0'
}Maven
xml
<dependency>
<groupId>io.github.logward-dev</groupId>
<artifactId>logward-sdk-kotlin</artifactId>
<version>0.2.0</version>
</dependency>Quick Start
kotlin
import dev.logward.sdk.LogWardClient
import dev.logward.sdk.models.LogWardClientOptions
val client = LogWardClient(
LogWardClientOptions(
apiUrl = "http://localhost:8080",
apiKey = "lp_your_api_key_here"
)
)
// Send logs
client.info("api-gateway", "Server started", mapOf("port" to 3000))
client.error("database", "Connection failed", RuntimeException("Timeout"))
// Graceful shutdown (also automatic on JVM shutdown)
runBlocking {
client.close()
}Features
- ✅ Automatic batching with configurable size and interval
- ✅ Retry logic with exponential backoff
- ✅ Circuit breaker pattern for fault tolerance
- ✅ Max buffer size with drop policy to prevent memory leaks
- ✅ Query API for searching and filtering logs
- ✅ Live tail with Server-Sent Events (SSE)
- ✅ Trace ID context for distributed tracing
- ✅ Global metadata added to all logs
- ✅ Structured error serialization
- ✅ Internal metrics (logs sent, errors, latency)
- ✅ Coroutines support for async operations
- ✅ Ktor Plugin for automatic HTTP logging
- ✅ Spring Boot Interceptor for automatic HTTP logging
- ✅ Jakarta Servlet Filter for automatic HTTP logging
- ✅ Kotlin Multiplatform ready
Configuration
kotlin
val client = LogWardClient(LogWardClientOptions(
// Required
apiUrl = "http://localhost:8080",
apiKey = "lp_your_api_key",
// Optional - Performance
batchSize = 100, // Max logs per batch (default: 100)
flushInterval = 5.seconds, // Flush interval (default: 5s)
maxBufferSize = 10000, // Max logs in buffer (default: 10000)
// Optional - Reliability
maxRetries = 3, // Max retry attempts (default: 3)
retryDelay = 1.seconds, // Initial retry delay (default: 1s)
circuitBreakerThreshold = 5, // Failures before circuit opens (default: 5)
circuitBreakerTimeout = 60.seconds, // Circuit reset timeout (default: 60s)
// Optional - Metadata
globalMetadata = mapOf( // Added to all logs
"environment" to "production",
"version" to "1.0.0"
),
// Optional - Features
enableMetrics = true, // Enable metrics collection (default: true)
debug = false // Enable debug logging (default: false)
))Logging Methods
Basic Logging
kotlin
// Log levels: debug, info, warn, error, critical
client.debug("service-name", "Debug message", mapOf("detail" to "value"))
client.info("api-gateway", "Request received", mapOf("method" to "GET", "path" to "/users"))
client.warn("cache", "Cache miss", mapOf("key" to "user:123"))
client.error("database", "Query failed", mapOf("query" to "SELECT *"))
client.critical("system", "Out of memory", mapOf("used" to "95%"))Error Logging with Auto-Serialization
kotlin
// Automatically serializes exception details
try {
database.connect()
} catch (e: SQLException) {
client.error("database", "Connection failed", e)
// Automatically includes: exception type, message, and stack trace
}Trace ID Context
kotlin
// Manual trace ID
client.withTraceId("550e8400-e29b-41d4-a716-446655440000") {
client.info("api", "Processing request")
client.info("db", "Query executed")
}
// Scoped trace ID (coroutines)
coroutineScope {
client.withTraceId("my-trace-id") {
launch { client.info("worker-1", "Task started") }
launch { client.info("worker-2", "Task started") }
}
}
// Auto-generated trace ID
client.withTraceId { // generates UUID
client.info("api", "Request processing")
}Middleware Integration
Ktor Plugin
Automatically log HTTP requests and responses in Ktor applications.
kotlin
import dev.logward.sdk.middleware.LogWardPlugin
import io.ktor.server.application.*
fun Application.module() {
install(LogWardPlugin) {
apiUrl = "http://localhost:8080"
apiKey = "lp_your_api_key_here"
serviceName = "ktor-app"
// Optional configuration
logRequests = true
logResponses = true
logErrors = true
skipHealthCheck = true
skipPaths = setOf("/metrics", "/internal")
// Client options
batchSize = 100
flushInterval = 5.seconds
enableMetrics = true
globalMetadata = mapOf("env" to "production")
}
}
// Access client manually in routes
routing {
get("/api/custom") {
val client = call.application.attributes[LogWardClientKey]
client.info("my-service", "Custom business logic executed",
mapOf("userId" to 123, "action" to "custom_operation"))
call.respondText("OK")
}
}Spring Boot Interceptor
Automatically log HTTP requests and responses in Spring Boot applications.
kotlin
import dev.logward.sdk.LogWardClient
import dev.logward.sdk.middleware.LogWardInterceptor
import dev.logward.sdk.models.LogWardClientOptions
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
@Configuration
class LogWardConfig : WebMvcConfigurer {
@Bean
fun logWardClient() = LogWardClient(
LogWardClientOptions(
apiUrl = "http://localhost:8080",
apiKey = "lp_your_api_key_here"
)
)
@Bean
fun logWardInterceptor(client: LogWardClient) = LogWardInterceptor(
client = client,
serviceName = "spring-boot-app",
logRequests = true,
logResponses = true,
skipHealthCheck = true
)
override fun addInterceptors(registry: InterceptorRegistry) {
registry.addInterceptor(logWardInterceptor(logWardClient()))
}
}Jakarta Servlet Filter
Automatically log HTTP requests and responses in Jakarta Servlet applications (Tomcat, Jetty, etc.).
kotlin
import dev.logward.sdk.LogWardClient
import dev.logward.sdk.middleware.LogWardFilter
import dev.logward.sdk.models.LogWardClientOptions
// Create client
val client = LogWardClient(
LogWardClientOptions(
apiUrl = "http://localhost:8080",
apiKey = "lp_your_api_key_here"
)
)
// Create filter
val filter = LogWardFilter(
client = client,
serviceName = "servlet-app",
logRequests = true,
logResponses = true,
skipHealthCheck = true
)
// Add to servlet context
servletContext.addFilter("logWard", filter)Query API
Basic Query
kotlin
// Search logs
val result = client.query(
service = "api-gateway",
level = "error",
from = "2025-01-15T00:00:00Z",
to = "2025-01-15T23:59:59Z",
limit = 100
)
println("Found ${result.total} error logs")
result.logs.forEach { log ->
println("[${log.time}] ${log.message}")
}Full-Text Search
kotlin
val result = client.query(
q = "timeout OR connection", // Full-text search
level = "error",
limit = 50
)Get Logs by Trace ID
kotlin
val logs = client.getLogsByTraceId(
traceId = "550e8400-e29b-41d4-a716-446655440000"
)
// Returns all logs with the same trace_id
logs.forEach { log ->
println("[${log.service}] ${log.message}")
}Live Streaming (SSE)
kotlin
// Stream logs in real-time
client.liveTail(
service = "api-gateway",
level = "error"
) { log ->
// Called for each new log
println("[${log.time}] ${log.message}")
}
// Stream will automatically reconnect on connection lossMetrics
kotlin
// Get internal metrics
val metrics = client.getMetrics()
println("Logs sent: ${metrics.logsSent}")
println("Logs failed: ${metrics.logsFailed}")
println("Avg latency: ${metrics.avgLatencyMs}ms")
println("Circuit breaker state: ${metrics.circuitBreakerState}")Best Practices
1. Use Middleware for HTTP Logging
Leverage built-in middleware plugins (Ktor, Spring Boot, Jakarta
Servlet) for automatic HTTP request/response logging instead of
manual instrumentation.
2. Use Coroutines for Async
Leverage Kotlin coroutines for non-blocking log operations in
high-concurrency applications.
3. Graceful Shutdown
Always call
client.close() on shutdown to ensure buffered
logs are flushed before JVM terminates. The SDK also registers an
automatic shutdown hook.4. Use Global Metadata
Set global metadata (environment, version) at initialization to
avoid repeating it in every log call.