From 878492280fdb0ed0306ee6f7b38e0da080b4ef27 Mon Sep 17 00:00:00 2001 From: Ido Berkovich Date: Tue, 17 Dec 2024 11:33:09 +0200 Subject: [PATCH] [OPIK-152] document log level (#857) * OPIK-152 document log level * OPIK-152 document logging and database * OPIK-152 document analytics database for migrations * OPIK-152 document analytics database for service * OPIK-152 document distributed locking * OPIK-152 document redis and authentication * OPIK-152 document server and batch operations * OPIK-152 document rate limit * OPIK-152 document usage report, metadata, cors and encryption * OPIK-152 document llm providers and refactor --- apps/opik-backend/config.yml | 138 +++++++++++++++++- .../opik/domain/ChatCompletionService.java | 4 +- .../LlmProviderClientConfig.java | 4 +- .../src/test/resources/config-test.yml | 107 +++++++++++++- 4 files changed, 238 insertions(+), 15 deletions(-) diff --git a/apps/opik-backend/config.yml b/apps/opik-backend/config.yml index 0e19446fcd..b58eb342ed 100644 --- a/apps/opik-backend/config.yml +++ b/apps/opik-backend/config.yml @@ -1,37 +1,87 @@ --- +# https://www.dropwizard.io/en/stable/manual/configuration.html#logging logging: + # Default: INFO + # Description: Logback logging level level: ${GENERAL_LOG_LEVEL:-INFO} + # Default: com.comet: INFO + # Description: Individual logger configuration loggers: com.comet: ${OPIK_LOG_LEVEL:-INFO} +# Description: state database configuration +# https://www.dropwizard.io/en/stable/manual/configuration.html#database database: + # Default: jdbc:mysql://localhost:3306/opik?createDatabaseIfNotExist=true&rewriteBatchedStatements=true + # Description: The URL of the server url: ${STATE_DB_PROTOCOL:-jdbc:mysql://}${STATE_DB_URL:-localhost:3306/opik?createDatabaseIfNotExist=true&rewriteBatchedStatements=true} + # Default: opik + # Description: The username used to connect to the server user: ${STATE_DB_USER:-opik} + # Default: opik + # Description: The password used to connect to the server password: ${STATE_DB_PASS:-opik} + # Default: com.mysql.cj.jdbc.Driver + # Description: The fully qualified class name of the JDBC driver class. + # Only required if there were no JDBC drivers registered in META-INF/services/java.sql.Driver. driverClass: ${STATE_DB_DRIVER_CLASS:-com.mysql.cj.jdbc.Driver} + # Default: Empty + # Description: Any additional JDBC driver parameters properties: wrapperPlugins: ${STATE_DB_PLUGINS:-''} -# For migrations +# Description: analytics database configuration for migrations connection databaseAnalyticsMigrations: + # Default: jdbc:clickhouse://localhost:8123/opik + # Description: The URL of the server url: ${ANALYTICS_DB_MIGRATIONS_URL:-jdbc:clickhouse://localhost:8123/opik} + # Default: opik + # Description: The username used to connect to the server user: ${ANALYTICS_DB_MIGRATIONS_USER:-opik} + # Default: opik + # Description: The password used to connect to the server password: ${ANALYTICS_DB_MIGRATIONS_PASS:-opik} - # Community support only. Requires an old driver for migrations to work + # Default: ru.yandex.clickhouse.ClickHouseDriver + # Description: The fully qualified class name of the JDBC driver class. + # Community support only. Requires an old driver for migrations to work driverClass: ru.yandex.clickhouse.ClickHouseDriver -# For service +# Description: analytics database configuration for service connection databaseAnalytics: + # Default: http + # Description: The protocol used to connect to the server protocol: ${ANALYTICS_DB_PROTOCOL:-HTTP} + # Default: localhost + # Description: The host used to connect to the server host: ${ANALYTICS_DB_HOST:-localhost} + # Default: 8123 + # Description: The port used to connect to the server port: ${ANALYTICS_DB_PORT:-8123} + # Default: opik + # Description: The username used to connect to the server username: ${ANALYTICS_DB_USERNAME:-opik} + # Default: opik + # Description: The password used to connect to the server password: ${ANALYTICS_DB_PASS:-opik} + # Default: opik + # Description: The database name databaseName: ${ANALYTICS_DB_DATABASE_NAME:-opik} + # Default: + # - health_check_interval=2000 + # - compress=1 + # - auto_discovery=true + # - failover=3 + # - custom_http_params=max_query_size=100000000 + # Description: query parameters that will be added to the connection string queryParameters: ${ANALYTICS_DB_QUERY_PARAMETERS:-health_check_interval=2000&compress=1&auto_discovery=true&failover=3&custom_http_params=max_query_size=100000000} +# https://www.dropwizard.io/en/stable/manual/configuration.html#health health: + # Default: ["/health-check"] + # Description: URLs to expose the app’s health check on. healthCheckUrlPaths: [ "/health-check" ] + # Options around a particular health check which is registered in an Application + # https://www.dropwizard.io/en/stable/manual/configuration.html#man-configuration-health-checks healthChecks: - name: deadlocks critical: true @@ -49,57 +99,133 @@ health: critical: true type: ready +# Configuration for distributed locking using redis distributedLock: + # Default: 500 + # Description: Lease time in milliseconds lockTimeoutMS: ${DISTRIBUTED_LOCK_TIME_OUT:-500} + # Default: 5 + # Description: This value has to be considerably higher than the lockTimeoutMS value, as it has to guarantee that the + # last thread to join the queue to acquire the lock will have enough time to execute the action. Then, the lock will + # be deleted from redis after the specified period of time. + # This is needed as redisson by default doesn't delete the lock from redis after the lease time expires, it just + # releases the lock. The expiration time will be reset every time the lock is acquired. ttlInSeconds: ${DISTRIBUTED_LOCK_TTL_IN_SEC:-5} +# Redis configuration redis: + # Default: + # Description: single node redis's URL singleNodeUrl: ${REDIS_URL:-} +# Authentication configuration. This is not enabled by default for open source installations. authentication: + # Default: false + # Description: Whether or not to enable authentication enabled: ${AUTH_ENABLED:-false} - apiKeyResolutionCacheTTLInSec: ${AUTH_API_KEY_RESOLUTION_CACHE_TTL_IN_SEC:-5} #0 means no cache + # Default: 5 + # Description: API key resolution cache TTL (seconds). Setting this value to 0 means no caching. + apiKeyResolutionCacheTTLInSec: ${AUTH_API_KEY_RESOLUTION_CACHE_TTL_IN_SEC:-5} + # Default: + # Description: Configures how to authenticate requests which originates from the sdk sdk: url: ${AUTH_SDK_URL:-''} + # Default: + # Description: Configures how to authenticate requests which originates from the ui ui: url: ${AUTH_UI_URL:-''} +# https://www.dropwizard.io/en/stable/manual/configuration.html#servers server: + # Default: false + # Description: Whether to enable virtual threads for Jetty’s thread pool. enableVirtualThreads: ${ENABLE_VIRTUAL_THREADS:-false} + # https://www.dropwizard.io/en/stable/manual/configuration.html#gzip gzip: + # Default: true + # Description: If true, all requests with gzip in the Accept-Encoding header will have their response entities + # compressed and requests with gzip in the Content-Encoding header will have their request entities decompressed. enabled: true +# Configuration for batch operations batchOperations: datasets: + # Default: 5000 + # Description: The maximal number of ids to be used for IN clause. Find requests with a larger number of ids will + # involve the use of temp tables for querying maxExperimentInClauseSize: ${BATCH_OPERATIONS_MAX_EXPERIMENT_IN_CLAUSE_SIZE:-5000} +# Configuration for rate limit. This is not enabled by default for open source installations. +# If enabled, rate limit is applied to creation and update of various entities including traces, spans, projects, +# prompts, feedback definitions, experiments, datasets and dataset items rateLimit: + # Default: false + # Description: Whether or not rate limit is enabled enabled: ${RATE_LIMIT_ENABLED:-false} + # This uses as a fallback rate limit configuration in case an entity specific configuration doesn't exist generalLimit: + # Default: 10000 + # Description: how many events are allowed in the specified time bucket limit: ${RATE_LIMIT_GENERAL_EVENTS_LIMIT:-10000} + # Default: 60 + # Description: Time bucket size in seconds durationInSeconds: ${RATE_LIMIT_GENERAL_EVENTS_DURATION_IN_SEC:-60} +# Configuration for anonymous usage reporting usageReport: + # Default: true + # Description: Whether or not to send anonymous usage reports enabled: ${OPIK_USAGE_REPORT_ENABLED:-true} + # Default: https://stats.comet.com/notify/event/ + # Description: URL to send the anonymous usage reports to url: ${OPIK_USAGE_REPORT_URL:-https://stats.comet.com/notify/event/} +# Configuration for application metadata metadata: + # Default: latest + # Description: The application version version: ${OPIK_VERSION:-latest} +# CORS related configuration cors: + # Default: false + # Description: Whether or not to allow cross site scripting enabled: ${CORS:-false} +# Encryption related configuration encryption: + # Default: GiTHubiLoVeYouAA + # Description: Encryption key to use when storing sensitive information key: ${OPIK_ENCRYPTION_KEY:-'GiTHubiLoVeYouAA'} +# LLM providers client configuration llmProviderClient: + # Default: 3 + # Description: Max amount of attempts to reach the LLM provider before giving up maxAttempts: ${LLM_PROVIDER_CLIENT_MAX_ATTEMPTS:-3} + # Default: 500 + # Description: Number of milliseconds to wait between retry attempts delayMillis: ${LLM_PROVIDER_CLIENT_DELAY_MILLIS:-500} + # Default: 0.2 + # Description: Max amount of jitter to add to the delay. The value is a percentage in the range [0-1] jitterScale: ${LLM_PROVIDER_CLIENT_JITTER_SCALE:-0.2} + # Default: 1.5 + # Description: Backoff exponent to be used in retry attempts backoffExp: ${LLM_PROVIDER_CLIENT_BACKOFF_EXP:-1.5} + # Default: 60s + # Description: Call timeout for LLM providers callTimeout: ${LLM_PROVIDER_CLIENT_CALL_TIMEOUT:-60s} + # Default: 60s + # Description: Connect timeout for LLM providers connectTimeout: ${LLM_PROVIDER_CLIENT_CONNECT_TIMEOUT:-60s} + # Default: 60s + # Description: Read timeout for LLM providers readTimeout: ${LLM_PROVIDER_CLIENT_READ_TIMEOUT:-60s} + # Default: 60s + # Description: Write timeout for LLM providers writeTimeout: ${LLM_PROVIDER_CLIENT_WRITE_TIMEOUT:-60s} - openApiClient: - url: ${LLM_PROVIDER_CLIENT_WRITE_TIMEOUT:-} + # Configuration for OpenAI client + openAiClient: + # Default: + # Description: OpenAI API URL + url: ${LLM_PROVIDER_OPENAI_URL:-} diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/ChatCompletionService.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/ChatCompletionService.java index dd6aa06aa8..e196a14b7a 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/ChatCompletionService.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/ChatCompletionService.java @@ -129,8 +129,8 @@ private String getEncryptedApiKey(String workspaceId, LlmProvider llmProvider) { */ private OpenAiClient newOpenAiClient(String encryptedApiKey) { var openAiClientBuilder = OpenAiClient.builder(); - Optional.ofNullable(llmProviderClientConfig.getOpenApiClient()) - .map(LlmProviderClientConfig.OpenApiClientConfig::url) + Optional.ofNullable(llmProviderClientConfig.getOpenAiClient()) + .map(LlmProviderClientConfig.OpenAiClientConfig::url) .ifPresent(baseUrl -> { if (StringUtils.isNotBlank(baseUrl)) { openAiClientBuilder.baseUrl(baseUrl); diff --git a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/LlmProviderClientConfig.java b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/LlmProviderClientConfig.java index bb32740560..584fce52b2 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/LlmProviderClientConfig.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/LlmProviderClientConfig.java @@ -12,7 +12,7 @@ @Data public class LlmProviderClientConfig { - public record OpenApiClientConfig(String url) { + public record OpenAiClientConfig(String url) { } @Min(1) @@ -38,5 +38,5 @@ public record OpenApiClientConfig(String url) { private Duration writeTimeout; @Valid - private OpenApiClientConfig openApiClient; + private LlmProviderClientConfig.OpenAiClientConfig openAiClient; } diff --git a/apps/opik-backend/src/test/resources/config-test.yml b/apps/opik-backend/src/test/resources/config-test.yml index ecabf312c7..7510a272be 100644 --- a/apps/opik-backend/src/test/resources/config-test.yml +++ b/apps/opik-backend/src/test/resources/config-test.yml @@ -1,35 +1,82 @@ --- +# https://www.dropwizard.io/en/stable/manual/configuration.html#logging logging: + # Default: INFO + # Description: Logback logging level level: INFO + # Default: com.comet: DEBUG + # Description: Individual logger configuration loggers: com.comet: DEBUG +# Description: state database configuration +# https://www.dropwizard.io/en/stable/manual/configuration.html#database database: + # Default: jdbc:mysql://localhost:3306/opik?createDatabaseIfNotExist=true&rewriteBatchedStatements=true + # Description: The URL of the server url: jdbc:mysql://localhost:3306/opik?createDatabaseIfNotExist=true&rewriteBatchedStatements=true + # Default: opik + # Description: The username used to connect to the server user: opik + # Default: opik + # Description: The password used to connect to the server password: opik + # Default: com.mysql.cj.jdbc.Driver + # Description: The fully qualified class name of the JDBC driver class. Only required if there were no JDBC drivers registered in META-INF/services/java.sql.Driver. driverClass: com.mysql.cj.jdbc.Driver -# For migrations +# Description: analytics database configuration for migrations connection databaseAnalyticsMigrations: + # Default: jdbc:clickhouse://localhost:8123/opik + # Description: The URL of the server url: jdbc:clickhouse://localhost:8123/opik + # Default: opik + # Description: The username used to connect to the server user: opik + # Default: opik + # Description: The password used to connect to the server password: opik - # Community support only. Requires an old driver for migrations to work + # Default: ru.yandex.clickhouse.ClickHouseDriver + # Description: The fully qualified class name of the JDBC driver class. + # Community support only. Requires an old driver for migrations to work driverClass: ru.yandex.clickhouse.ClickHouseDriver -# For service +# Description: analytics database configuration for service connection databaseAnalytics: + # Default: http + # Description: The protocol used to connect to the server protocol: HTTP + # Default: localhost + # Description: The host used to connect to the server host: localhost + # Default: 8123 + # Description: The port used to connect to the server port: 8123 + # Default: opik + # Description: The username used to connect to the server username: opik + # Default: opik + # Description: The password used to connect to the server password: opik + # Default: opik + # Description: The database name databaseName: opik + # Default: + # - health_check_interval=2000 + # - compress=1 + # - auto_discovery=true + # - failover=3 + # - custom_http_params=max_query_size=100000000 + # Description: query parameters that will be added to the connection string queryParameters: health_check_interval=2000&compress=1&auto_discovery=true&failover=3&custom_http_params=max_query_size=100000000 +# https://www.dropwizard.io/en/stable/manual/configuration.html#health health: + # Default: ["/health-check"] + # Description: URLs to expose the app’s health check on. healthCheckUrlPaths: [ "/health-check" ] + # Options around a particular health check which is registered in an Application + # https://www.dropwizard.io/en/stable/manual/configuration.html#man-configuration-health-checks healthChecks: - name: deadlocks critical: true @@ -47,47 +94,97 @@ health: critical: true type: ready +# Configuration for distributed locking using redis distributedLock: + # Default: 500 + # Description: Lease time in milliseconds lockTimeout: 500 + # Default: 1 + # Description: This value has to be considerably higher than the lockTimeoutMS value, as it has to guarantee that the + # last thread to join the queue to acquire the lock will have enough time to execute the action. Then, the lock will + # be deleted from redis after the specified period of time. + # This is needed as redisson by default doesn't delete the lock from redis after the lease time expires, it just + # releases the lock. The expiration time will be reset every time the lock is acquired. ttlInSeconds: 1 +# Redis configuration redis: + # Default: + # Description: single node redis's URL singleNodeUrl: +# Authentication configuration. This is not enabled by default for open source installations. authentication: + # Default: false + # Description: Whether or not to enable authentication enabled: ${AUTH_ENABLED:-false} - apiKeyResolutionCacheTTLInSec: ${AUTH_API_KEY_RESOLUTION_CACHE_TTL_IN_SEC:-0} #0 means no cache + # Default: 0 + # Description: API key resolution cache TTL (seconds). Setting this value to 0 means no caching. + apiKeyResolutionCacheTTLInSec: ${AUTH_API_KEY_RESOLUTION_CACHE_TTL_IN_SEC:-0} + # Default: + # Description: Configures how to authenticate requests which originates from the sdk sdk: url: ${AUTH_SDK_URL:-''} + # Default: + # Description: Configures how to authenticate requests which originates from the ui ui: url: ${AUTH_UI_URL:-''} +# https://www.dropwizard.io/en/stable/manual/configuration.html#servers server: + # Default: false + # Description: Whether to enable virtual threads for Jetty’s thread pool. enableVirtualThreads: false + # https://www.dropwizard.io/en/stable/manual/configuration.html#gzip gzip: + # Default: true + # Description: If true, all requests with gzip in the Accept-Encoding header will have their response entities + # compressed and requests with gzip in the Content-Encoding header will have their request entities decompressed. enabled: true +# Configuration for batch operations batchOperations: datasets: + # Default: 100 + # Description: The maximal number of ids to be used for IN clause. Find requests with a larger number of ids will + # involve the use of temp tables for querying maxExperimentInClauseSize: 100 +# Configuration for rate limit. This is not enabled by default for open source installations. +# If enabled, rate limit is applied to creation and update of various entities including traces, spans, projects, +# prompts, feedback definitions, experiments, datasets and dataset items rateLimit: + # Default: false + # Description: Whether or not rate limit is enabled enabled: false +# Configuration for anonymous usage reporting usageReport: + # Default: false + # Description: Whether or not to send anonymous usage reports enabled: false +# Configuration for application metadata metadata: + # Default: latest + # Description: The application version version: ${OPIK_VERSION:-latest} +# CORS related configuration cors: + # Default: false + # Description: Whether or not to allow cross site scripting enabled: ${CORS:-false} +# Encryption related configuration encryption: + # Default: GiTHubiLoVeYouAA + # Description: Encryption key to use when storing sensitive information key: ${OPIK_ENCRYPTION_KEY:-'GiTHubiLoVeYouAA'} +# LLM providers client configuration llmProviderClient: - openApiClient: + openAiClient: # See demo endpoint Langchain4j documentation: https://docs.langchain4j.dev/get-started # Not https but only used for testing purposes. It's fine as long as not sensitive data is sent. url: http://langchain4j.dev/demo/openai/v1