# Enabling logging

Below are examples of code that enables logging in different YDB SDKs.

There are several ways to enable logs in an application that uses ydb-go-sdk:

Using the YDB_LOG_SEVERITY_LEVEL environment variable

This environment variable enables the built-in ydb-go-sdk logger (synchronous, non-block) and prints to the standard output stream.
You can set the environment variable as follows:

export YDB_LOG_SEVERITY_LEVEL=info

(possible values: trace, debug, info, warn, error, fatal, and quiet, defaults to quiet).

Enable a third-party logger go.uber.org/zap
package main

import (
  "context"
  "os"

  "go.uber.org/zap"

  ydbZap "github.com/ydb-platform/ydb-go-sdk-zap"
  "github.com/ydb-platform/ydb-go-sdk/v3"
  "github.com/ydb-platform/ydb-go-sdk/v3/trace"
)

func main() {
  ctx, cancel := context.WithCancel(context.Background())
  defer cancel()
  var log *zap.Logger // zap-logger with init out of this scope
  db, err := ydb.Open(ctx,
    os.Getenv("YDB_CONNECTION_STRING"),
    ydbZap.WithTraces(
      log,
      trace.DetailsAll,
    ),
  )
  if err != nil {
    panic(err)
  }
  defer db.Close(ctx)
  ...
}
Enable a third-party logger github.com/rs/zerolog
package main

import (
  "context"
  "os"

  "github.com/rs/zerolog"

  ydbZerolog "github.com/ydb-platform/ydb-go-sdk-zerolog"
  "github.com/ydb-platform/ydb-go-sdk/v3"
  "github.com/ydb-platform/ydb-go-sdk/v3/trace"
)

func main() {
  ctx, cancel := context.WithCancel(context.Background())
  defer cancel()
  var log zerolog.Logger // zap-logger with init out of this scope
  db, err := ydb.Open(ctx,
    os.Getenv("YDB_CONNECTION_STRING"),
    ydbZerolog.WithTraces(
      &log,
      trace.DetailsAll,
    ),
  )
  if err != nil {
    panic(err)
  }
  defer db.Close(ctx)
  ...
}
Enable a custom logger implementation github.com/ydb-platform/ydb-go-sdk/v3/log.Logger
package main

import (
  "context"
  "os"

  "github.com/ydb-platform/ydb-go-sdk/v3"
  "github.com/ydb-platform/ydb-go-sdk/v3/log"
  "github.com/ydb-platform/ydb-go-sdk/v3/trace"
)

func main() {
  ctx, cancel := context.WithCancel(context.Background())
  defer cancel()
  var logger log.Logger // logger implementation with init out of this scope
  db, err := ydb.Open(ctx,
    os.Getenv("YDB_CONNECTION_STRING"),
    ydb.WithLogger(
      logger,
      trace.DetailsAll,
    ),
  )
  if err != nil {
    panic(err)
  }
  defer db.Close(ctx)
  ...
}
Implement your own logging package

You can implement your own logging package based on the driver events in the github.com/ydb-platform/ydb-go-sdk/v3/trace tracing package. The github.com/ydb-platform/ydb-go-sdk/v3/trace tracing package describes all logged driver events.

Iterate over server errors with IterateByIssues

When using YDB through the Go SDK, you can enable logging of requests and responses and also obtain detailed information about server errors (issues) — extra messages YDB returns in the response when operations fail. To iterate over issues in the server response, use IterateByIssues.

There are several ways to enable logs in an application that uses ydb-go-sdk:

Using the YDB_LOG_SEVERITY_LEVEL environment variable

This environment variable enables the built-in ydb-go-sdk logger (synchronous, non-block) and prints to the standard output stream.
You can set the environment variable as follows:

export YDB_LOG_SEVERITY_LEVEL=info

(possible values: trace, debug, info, warn, error, fatal, and quiet, defaults to quiet).

Enable a third-party logger go.uber.org/zap
package main

import (
  "context"
  "database/sql"
  "os"

  "go.uber.org/zap"

  ydbZap "github.com/ydb-platform/ydb-go-sdk-zap"
  "github.com/ydb-platform/ydb-go-sdk/v3"
  "github.com/ydb-platform/ydb-go-sdk/v3/trace"
)

func main() {
  ctx, cancel := context.WithCancel(context.Background())
  defer cancel()
  var log *zap.Logger // zap-logger with init out of this scope
  nativeDriver, err := ydb.Open(ctx,
    os.Getenv("YDB_CONNECTION_STRING"),
    ydbZap.WithTraces(
      log,
      trace.DetailsAll,
    ),
  )
  if err != nil {
    panic(err)
  }
  defer nativeDriver.Close(ctx)

  connector, err := ydb.Connector(nativeDriver)
  if err != nil {
    panic(err)
  }
  defer connector.Close()

  db := sql.OpenDB(connector)
  defer db.Close()
  ...
}
Enable a third-party logger github.com/rs/zerolog
package main

import (
  "context"
  "database/sql"
  "os"

  "github.com/rs/zerolog"

  ydbZerolog "github.com/ydb-platform/ydb-go-sdk-zerolog"
  "github.com/ydb-platform/ydb-go-sdk/v3"
  "github.com/ydb-platform/ydb-go-sdk/v3/trace"
)

func main() {
  ctx, cancel := context.WithCancel(context.Background())
  defer cancel()
  var log zerolog.Logger // zap-logger with init out of this scope
  nativeDriver, err := ydb.Open(ctx,
    os.Getenv("YDB_CONNECTION_STRING"),
    ydbZerolog.WithTraces(
      &log,
      trace.DetailsAll,
    ),
  )
  if err != nil {
    panic(err)
  }
  defer nativeDriver.Close(ctx)

  connector, err := ydb.Connector(nativeDriver)
  if err != nil {
    panic(err)
  }
  defer connector.Close()

  db := sql.OpenDB(connector)
  defer db.Close()
  ...
}
Enable a custom logger implementation github.com/ydb-platform/ydb-go-sdk/v3/log.Logger
package main

import (
  "context"
  "database/sql"
  "os"

  "github.com/ydb-platform/ydb-go-sdk/v3"
  "github.com/ydb-platform/ydb-go-sdk/v3/log"
  "github.com/ydb-platform/ydb-go-sdk/v3/trace"
)

func main() {
  ctx, cancel := context.WithCancel(context.Background())
  defer cancel()
  var logger log.Logger // logger implementation with init out of this scope
  nativeDriver, err := ydb.Open(ctx,
    os.Getenv("YDB_CONNECTION_STRING"),
    ydb.WithLogger(
      logger,
      trace.DetailsAll,
    ),
  )
  if err != nil {
    panic(err)
  }
  defer nativeDriver.Close(ctx)

  connector, err := ydb.Connector(nativeDriver)
  if err != nil {
    panic(err)
  }
  defer connector.Close()

  db := sql.OpenDB(connector)
  defer db.Close()
  ...
}
Implement your own logging package

You can implement your own logging package based on the driver events in the github.com/ydb-platform/ydb-go-sdk/v3/trace tracing package. The github.com/ydb-platform/ydb-go-sdk/v3/trace tracing package describes all logged driver events.

For logging purposes, the YDB Java SDK uses the slf4j library, which supports multiple logging levels (error, warn, info, debug, trace) for one or many loggers. The current implementation supports the following loggers:

  • The tech.ydb.core.grpc logger provides information about the internal gRPC implementation
  • The debug level logs all gRPC operations; use it only for debugging
  • The info level is recommended by default
  • On the debug level, the tech.ydb.table.impl logger lets you track the internal state of the YDB driver, including the session pool
  • On the debug level, the tech.ydb.table.SessionRetryContext logger reports the number of retries, query results, per-retry duration, and total operation time
  • On the debug level, the tech.ydb.table.Session logger provides the query text, response status, and execution time for session operations

Enabling and configuring the Java SDK loggers depends on the slf4j-api implementation you use.
Here is an example log4j2 configuration for the log4j-slf4j-impl library:

<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>

  <Loggers>
    <Logger name="io.netty" level="warn" additivity="false">
      <AppenderRef ref="Console"/>
    </Logger>
    <Logger name="io.grpc.netty" level="warn" additivity="false">
      <AppenderRef ref="Console"/>
    </Logger>
    <Logger name="tech.ydb.core.grpc" level="info" additivity="false">
      <AppenderRef ref="Console"/>
    </Logger>
    <Logger name="tech.ydb.table.impl" level="info" additivity="false">
      <AppenderRef ref="Console"/>
    </Logger>
    <Logger name="tech.ydb.table.SessionRetryContext" level="debug" additivity="false">
      <AppenderRef ref="Console"/>
    </Logger>
    <Logger name="tech.ydb.table.Session" level="debug" additivity="false">
      <AppenderRef ref="Console"/>
    </Logger>

    <Root level="debug" >
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

The JDBC driver uses the same logging stack via slf4j; configure the tech.ydb.* loggers the same way as in the native SDK.

The same debug logs are available in other stacks built on JDBC (Spring Boot, ORMs, connection pools, and so on): they reach YDB through this driver, so it is enough to attach the same slf4j / log4j2 / logback configuration in the application.

For logging purposes, you need to use a class, that implements \Psr\Log\LoggerInterface.
ydb-php-sdk has build-in loggers in YdbPlatform\Ydb\Logger namespace:

  • NullLogger - default logger, which writes nothing
  • SimpleStdLogger($level) - logger, which writes to logs in stderr.

Usage example:

$config = [
  'logger' => new \YdbPlatform\Ydb\Logger\SimpleStdLogger(\YdbPlatform\Ydb\Logger\SimpleStdLogger::INFO)
]
$ydb = new \YdbPlatform\Ydb\Ydb($config);

The Python SDK uses the standard logging library. To enable a specific logging level:

import logging

logging.getLogger('ydb').setLevel(logging.DEBUG)

The SDK uses the debug library for logging.
To enable logs, set the DEBUG environment variable to filter SDK events, for example DEBUG=ydbjs:*.