logtide-dev/logtide-kotlin-java

GitHub: logtide-dev/logtide-kotlin-java

LogTide 官方 Kotlin SDK,为 Spring Boot 和 Ktor 应用提供具备批量处理、重试、断路器和实时流能力的日志集成方案。

Stars: 2 | Forks: 2

LogTide Logo

LogTide Kotlin SDK

Maven Central License Kotlin Release

LogTide 的官方 Kotlin SDK,支持自动批量处理、重试逻辑、断路器、查询 API、实时流以及 middleware 支持。

## 功能 - ✅ **自动批量处理**,支持可配置的大小和间隔 - ✅ **重试逻辑**,支持指数退避 - ✅ **断路器**模式,用于容错 - ✅ **最大缓冲区大小**,带有丢弃策略以防止内存泄漏 - ✅ **查询 API**,用于搜索和过滤日志 - ✅ **实时跟踪**,基于 Server-Sent Events (SSE) - ✅ **Trace ID 上下文**,用于分布式追踪 - ✅ **全局 metadata**,添加到所有日志中 - ✅ **结构化错误序列化** - ✅ **内部指标**(已发送日志、错误、延迟等) - ✅ **Spring Boot, Ktor middleware**,用于自动记录 HTTP 请求 - ✅ **完全支持 Kotlin 协程**,带有 `suspend` 函数 ## 环境要求 - JVM 11 或更高版本 - Kotlin 1.9+(或 Java 11+ 用于 Java 互操作) - Gradle 或 Maven ## 安装说明 ### Gradle (Kotlin DSL) ``` dependencies { implementation("io.github.logtide-dev:logtide-sdk-kotlin:0.2.0") } ``` ### Gradle (Groovy) ``` dependencies { implementation 'io.github.logtide-dev:logtide-sdk-kotlin:0.2.0' } ``` ### Maven ``` io.github.logtide-dev logtide-sdk-kotlin 0.2.0 ``` ## 快速开始 ``` import dev.logtide.sdk.LogTideClient import dev.logtide.sdk.models.LogTideClientOptions val client = LogTideClient( LogTideClientOptions( 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() } ``` ## 配置选项 ### 基本选项 | 选项 | 类型 | 默认值 | 描述 | |--------|------|---------|-------------| | `apiUrl` | `String` | **必填** | LogTide 实例的 Base URL | | `apiKey` | `String` | **必填** | 项目 API key(以 `lp_` 开头) | | `batchSize` | `Int` | `100` | 发送前批量处理的日志数量 | | `flushInterval` | `Duration` | `5.seconds` | 自动刷新日志的间隔 | ### 高级选项 | 选项 | 类型 | 默认值 | 描述 | |--------|------|---------|-------------| | `maxBufferSize` | `Int` | `10000` | 缓冲区中的最大日志数(防止内存泄漏) | | `maxRetries` | `Int` | `3` | 失败时的最大重试次数 | | `retryDelay` | `Duration` | `1.seconds` | 初始重试延迟(指数退避) | | `circuitBreakerThreshold` | `Int` | `5` | 触发断路器开启前的失败次数 | | `circuitBreakerReset` | `Duration` | `30.seconds` | 断路器开启后重试前的等待时间 | | `enableMetrics` | `Boolean` | `true` | 跟踪内部指标 | | `debug` | `Boolean` | `false` | 启用控制台的 debug 日志记录 | | `globalMetadata` | `Map` | `emptyMap()` | 添加到所有日志的 metadata | ### 示例:完整配置 ``` import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.milliseconds val client = LogTideClient( LogTideClientOptions( apiUrl = "http://localhost:8080", apiKey = "lp_your_api_key_here", // Batching batchSize = 100, flushInterval = 5.seconds, // Buffer management maxBufferSize = 10000, // Retry with exponential backoff (1s → 2s → 4s) maxRetries = 3, retryDelay = 1.seconds, // Circuit breaker circuitBreakerThreshold = 5, circuitBreakerReset = 30.seconds, // Metrics & debugging enableMetrics = true, debug = true, // Global context globalMetadata = mapOf( "env" to System.getenv("APP_ENV"), "version" to "1.0.0", "hostname" to System.getenv("HOSTNAME") ), ) ) ``` ## 日志记录方法 ### 基本日志记录 ``` client.debug("service-name", "Debug message") client.info("service-name", "Info message", mapOf("userId" to 123)) client.warn("service-name", "Warning message") client.error("service-name", "Error message", mapOf("custom" to "data")) client.critical("service-name", "Critical message") ``` ### 错误日志记录与自动序列化 SDK 会自动序列化 `Throwable` 对象: ``` try { throw RuntimeException("Database timeout") } catch (e: Exception) { // Automatically serializes error with stack trace client.error("database", "Query failed", e) } ``` 生成的日志 metadata: ``` { "error": { "name": "RuntimeException", "message": "Database timeout", "stack": "..." } } ``` ## Trace ID 上下文 使用 trace ID 跨服务跟踪请求。 ### 手动设置 Trace ID ``` client.setTraceId("request-123") client.info("api", "Request received") client.info("database", "Querying users") client.info("api", "Response sent") client.setTraceId(null) // Clear context ``` ### 作用域内的 Trace ID ``` client.withTraceId("request-456") { client.info("api", "Processing in context") client.warn("cache", "Cache miss") } // Trace ID automatically restored after block ``` ### 自动生成的 Trace ID ``` client.withNewTraceId { client.info("worker", "Background job started") client.info("worker", "Job completed") } ``` ## 查询 API 以编程方式搜索和检索日志。 ### 基本查询 ``` import dev.logtide.sdk.models.QueryOptions import dev.logtide.sdk.enums.LogLevel import java.time.Instant import java.time.temporal.ChronoUnit val result = client.query( QueryOptions( service = "api-gateway", level = LogLevel.ERROR, from = Instant.now().minus(24, ChronoUnit.HOURS), to = Instant.now(), limit = 100, offset = 0 ) ) println("Found ${result.total} logs") result.logs.forEach { log -> println(log) } ``` ### 全文搜索 ``` val result = client.query( QueryOptions( q = "timeout", limit = 50 ) ) ``` ### 根据 Trace ID 获取日志 ``` val logs = client.getByTraceId("trace-123") println("Trace has ${logs.size} logs") ``` ## 实时流 (SSE) 使用 Server-Sent Events 实时流式传输日志。 ``` val cleanup = client.stream( onLog = { log -> println("[${log.time}] ${log.level}: ${log.message}") }, onError = { error -> println("Stream error: ${error.message}") }, filters = mapOf( "service" to "api-gateway", "level" to "error" ) ) // Stop streaming when done Thread.sleep(60000) cleanup() ``` ## 指标 跟踪 SDK 的性能和健康状态。 ``` val metrics = client.getMetrics() println("Logs sent: ${metrics.logsSent}") println("Logs dropped: ${metrics.logsDropped}") println("Errors: ${metrics.errors}") println("Retries: ${metrics.retries}") println("Avg latency: ${metrics.avgLatencyMs}ms") println("Circuit breaker trips: ${metrics.circuitBreakerTrips}") // Get circuit breaker state println(client.getCircuitBreakerState()) // CLOSED, OPEN, or HALF_OPEN // Reset metrics client.resetMetrics() ``` ## Middleware 集成 LogTide 为流行的框架提供了开箱即用的 middleware。 ### Ktor 插件 在 Ktor 应用中自动记录 HTTP 请求和响应。 ``` import dev.logtide.sdk.middleware.LogTidePlugin import io.ktor.server.application.* fun Application.module() { val apiUrl = "http://localhost:8080" val apiKey = "lp_your_api_key_here" install(LogTidePlugin) { serviceName = "ktor-app" // Optional configuration logErrors = true skipHealthCheck = true skipPaths = setOf("/metrics", "/internal") // Client options logtideClientOptions(apiUrl, apiKey) { batchSize = 100 flushInterval = kotlin.time.Duration.parse("5s") enableMetrics = true globalMetadata = mapOf("env" to "production") } // Enable request/response logging logRequests = true // Log incoming requests, e.g., method, path, headers logResponses = true // Log outgoing responses stats, e.g., status code, duration // Customize metadata extraction from calls, e.g., add user ID, session info, etc. extractMetadataFromIncomingCall = { call, traceId -> mapOf( "method" to call.request.httpMethod.value, "path" to call.request.uri, "remoteHost" to call.request.local.remoteHost, "traceId" to traceId ) } // Customize metadata extraction from responses, e.g., status code, time elapsed, etc. extractMetadataFromOutgoingContent = { call, traceId, duration -> val statusValue = call.response.status()?.value val metadata = mutableMapOf( "method" to call.request.httpMethod.value, "path" to call.request.uri, "status" to (statusValue ?: 0), "duration" to (duration ?: 0L), "traceId" to traceId ) metadata } // Extract trace ID from incoming requests (if any) // useful for using in combination with the CallId plugin extractTraceIdFromCall = { call -> call.request.headers["X-Trace-ID"] } // Whether to use the default interceptor to propagate trace IDs in call context // if you plan to access the client manually in routes useDefaultInterceptor = true } } ``` **查看完整示例:** [examples/middleware/ktor/KtorExample.kt](examples/middleware/ktor/KtorExample.kt) #### 在 Ktor 中手动访问 Client 你可以直接在你的路由中访问 LogTide client 以进行自定义日志记录: ``` import dev.logtide.sdk.middleware.LogTideClientKey routing { get("/api/custom") { // Get the client from application attributes val client = call.application.attributes[LogTideClientKey] // Log custom messages client.info( "my-service", "Custom business logic executed", mapOf("userId" to 123, "action" to "custom_operation") ) call.respondText("OK") } } ``` ### Spring Boot 拦截器 在 Spring Boot 应用中自动记录 HTTP 请求和响应。 ``` import dev.logtide.sdk.LogTideClient import dev.logtide.sdk.middleware.LogTideInterceptor import dev.logtide.sdk.models.LogTideClientOptions 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 LogTideConfig : WebMvcConfigurer { @Bean fun logTideClient() = LogTideClient( LogTideClientOptions( apiUrl = "http://localhost:8080", apiKey = "lp_your_api_key_here" ) ) @Bean fun logTideInterceptor(client: LogTideClient) = LogTideInterceptor( client = client, serviceName = "spring-boot-app", logRequests = true, logResponses = true, skipHealthCheck = true ) override fun addInterceptors(registry: InterceptorRegistry) { registry.addInterceptor(logTideInterceptor(logTideClient())) } } ``` **查看完整示例:** [examples/middleware/spring-boot/SpringBootExample.kt](examples/middleware/spring-boot/SpringBootExample.kt) ### Jakarta Servlet 过滤器 在 Jakarta Servlet 应用中自动记录 HTTP 请求和响应(Tomcat、Jetty 等)。 ``` import dev.logtide.sdk.LogTideClient import dev.logtide.sdk.middleware.LogTideFilter import dev.logtide.sdk.models.LogTideClientOptions // Create client val client = LogTideClient( LogTideClientOptions( apiUrl = "http://localhost:8080", apiKey = "lp_your_api_key_here" ) ) // Create filter val filter = LogTideFilter( client = client, serviceName = "servlet-app", logRequests = true, logResponses = true, skipHealthCheck = true ) // Add to servlet context servletContext.addFilter("logTide", filter) ``` **或者通过 web.xml:** ``` LogTideFilter dev.logtide.sdk.middleware.LogTideFilter LogTideFilter /* ``` **查看完整示例:** [examples/middleware/jakarta-servlet/JakartaServletExample.kt](examples/middleware/jakarta-servlet/JakartaServletExample.kt) ## 开源协议 MIT 许可证 - 详情请参阅 [LICENSE](LICENSE)。 ## 链接 - [LogTide 官网](https://logtide.dev) - [文档](https://logtide.dev/docs/sdks/kotlin/) - [GitHub Issues](https://github.com/logtide-dev/logtide-sdk-kotlin/issues)
标签:JS文件枚举, Kotlin, Ktor, OISF, Spring Boot, 分布式追踪, 后台面板检测, 后端开发, 日志管理