Configuration

In addition to configuring your database connections in application.conf you can also set some global options in this file or through system properties (see the Typesafe Config documentation for details). These are the available options and their default values as defined in Slick’s own reference.conf:

# These settings are read by slick.util.SlickConfig
slick {
  # Use ANSI color sequences in tree dumps (as used in log messages and
  # exceptions of type SlickTreeException).
  ansiDump = false

  # Use Unicode box characters in tree and table dumps (as used in log
  # messages). If this option is not enabled, ASCII approximations are used
  # instead.
  unicodeDump = false

  # Dump individual "Select" and "Ref" nodes instead of combining them into a
  # single "Path" element when creating a tree dump (as used in log messages
  # and exceptions of type SlickTreeException).
  dumpPaths = false

  # Use multi-line, indented formatting for SQL statements. If not enabled,
  # statements are generated without any linebreaks or indentation. This
  # option applies to all generated statements (but not to the Plain SQL API).
  sqlIndent = false

  # Verify types after each query compiler phase. This is useful for debugging
  # the query compiler but should generally not be enabled in production
  # environments because it makes query compilation considerably slower.
  verifyTypes = false

  # Detect unnecessary rebuilding of the AST after every query compiler phase.
  # This is useful for debugging the query compiler. Query compilation
  # performance is negatively affected by this if phase logging is enabled.
  detectRebuild = false
}

# Profile-specific settings for MySQLProfile
slick.jdbc.MySQLProfile {
  # The default SQL type for strings without an explicit size limit.
  # When set to null / undefined, pick "TEXT" where possible, otherwise fall back
  # to "VARCHAR(254)"
  defaultStringType = null
}

# Profile-specific settings for SQLServerProfile
slick.jdbc.SQLServerProfile {
  # The default SQL type for strings without an explicit size limit.
  # When set to null / undefined, pick "TEXT" where possible, otherwise fall back to "VARCHAR(254)"
  defaultStringType = null
}

Logging

Slick uses SLF4J for logging. How to configure loggers and appenders depends on the actual logging framework that you use in your application. The following Logback configuration is used internally for testing and debugging of Slick. It contains a list of all loggers that are used by Slick for debug output:

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>*** \(%logger{30}\)%green(%X{debugId}) %msg%n</pattern>
        </encoder>
    </appender>
    <root level="${log.root:-info}">
        <appender-ref ref="STDOUT" />
    </root>
    <logger name="slick.basic.BasicBackend.action"          level="${log.action:-info}" />
    <logger name="slick.basic.BasicBackend.stream"          level="${log.stream:-info}" />
    <logger name="slick.compiler"                           level="${log.qcomp:-info}" />
    <logger name="slick.compiler.QueryCompiler"             level="${log.qcomp.phases:-inherited}" />
    <logger name="slick.compiler.QueryCompilerBenchmark"    level="${log.qcomp.bench:-inherited}" />
    <logger name="slick.compiler.Inline"                    level="${log.qcomp.inline:-inherited}" />
    <logger name="slick.compiler.AssignUniqueSymbols"       level="${log.qcomp.assignUniqueSymbols:-inherited}" />
    <logger name="slick.compiler.InferTypes"                level="${log.qcomp.inferTypes:-inherited}" />
    <logger name="slick.compiler.ExpandTables"              level="${log.qcomp.expandTables:-inherited}" />
    <logger name="slick.compiler.EmulateOuterJoins"         level="${log.qcomp.emulateOuterJoins:-inherited}" />
    <logger name="slick.compiler.ForceOuterBinds"           level="${log.qcomp.forceOuterBinds:-inherited}" />
    <logger name="slick.compiler.RemoveMappedTypes"         level="${log.qcomp.removeMappedTypes:-inherited}" />
    <logger name="slick.compiler.CreateResultSetMapping"    level="${log.qcomp.createResultSetMapping:-inherited}" />
    <logger name="slick.compiler.ExpandSums"                level="${log.qcomp.expandSums:-inherited}" />
    <logger name="slick.compiler.ExpandRecords"             level="${log.qcomp.expandRecords:-inherited}" />
    <logger name="slick.compiler.ExpandConditionals"        level="${log.qcomp.expandConditionals:-inherited}" />
    <logger name="slick.compiler.FlattenProjections"        level="${log.qcomp.flattenProjections:-inherited}" />
    <logger name="slick.compiler.CreateAggregates"          level="${log.qcomp.createAggregates:-inherited}" />
    <logger name="slick.compiler.RewriteJoins"              level="${log.qcomp.rewriteJoins:-inherited}" />
    <logger name="slick.compiler.RemoveTakeDrop"            level="${log.qcomp.removeTakeDrop:-inherited}" />
    <logger name="slick.compiler.ResolveZipJoins"           level="${log.qcomp.resolveZipJoins:-inherited}" />
    <logger name="slick.compiler.HoistClientOps"            level="${log.qcomp.hoistClientOps:-inherited}" />
    <logger name="slick.compiler.ReorderOperations"         level="${log.qcomp.reorderOperations:-inherited}" />
    <logger name="slick.compiler.MergeToComprehensions"     level="${log.qcomp.mergeToComprehensions:-inherited}" />
    <logger name="slick.compiler.OptimizeScalar"            level="${log.qcomp.optimizeScalar:-inherited}" />
    <logger name="slick.compiler.FixRowNumberOrdering"      level="${log.qcomp.fixRowNumberOrdering:-inherited}" />
    <logger name="slick.compiler.PruneProjections"          level="${log.qcomp.pruneProjections:-inherited}" />
    <logger name="slick.compiler.RewriteDistinct"           level="${log.qcomp.rewriteDistinct:-inherited}" />
    <logger name="slick.compiler.RewriteBooleans"           level="${log.qcomp.rewriteBooleans:-inherited}" />
    <logger name="slick.compiler.SpecializeParameters"      level="${log.qcomp.specializeParameters:-inherited}" />
    <logger name="slick.compiler.CodeGen"                   level="${log.qcomp.codeGen:-inherited}" />
    <logger name="slick.compiler.RemoveFieldNames"          level="${log.qcomp.removeFieldNames:-inherited}" />
    <logger name="slick.compiler.InsertCompiler"            level="${log.qcomp.insertCompiler:-inherited}" />
    <logger name="slick.compiler.VerifyTypes"               level="${log.qcomp.verifyTypes:-inherited}" />
    <logger name="slick.jdbc.DriverDataSource"              level="${log.jdbc.driver:-info}" />
    <logger name="slick.jdbc.JdbcBackend.statement"         level="${log.jdbc.statement:-info}" />
    <logger name="slick.jdbc.JdbcBackend.parameter"         level="${log.jdbc.parameter:-info}" />
    <logger name="slick.jdbc.JdbcBackend.benchmark"         level="${log.jdbc.bench:-info}" />
    <logger name="slick.jdbc.StatementInvoker.result"       level="${log.jdbc.result:-info}" />
    <logger name="slick.jdbc.JdbcModelBuilder"              level="${log.createModel:-info}" />
    <logger name="slick.memory.HeapBackend"                 level="${log.heap:-inherited}" />
    <logger name="slick.memory.QueryInterpreter"            level="${log.interpreter:-inherited}" />
    <logger name="slick.relational.ResultConverterCompiler" level="${log.resultConverter:-inherited}" />
    <logger name="slick.util.AsyncExecutor"                 level="${log.asyncExecutor:-inherited}" />
</configuration>

Note

Messages on WARNING and ERROR levels may also be emitted by loggers that are not explicitly mentioned in this configuration.

You should generally enable logging for the root package slick at level INFO (currently unused) or WARNING. Debug logging should only be enabled selectively for individual loggers, otherwise you will get a huge amount of log output.

The following loggers are particularly interesting:

slick.basic.BasicBackend.action
Shows the execution of every Database I/O Action.
slick.compiler.QueryCompiler
Shows a dump of the AST after every phase of the query compiler when compiling a query.
slick.jdbc.DriverDataSource
Shows information about JDBC drivers being loaded by DriverDataSource. Does not apply when using a connection pool unless you explicitly use a DriverDataSource as the source for the connection pool.
slick.jdbc.JdbcBackend.statement
Shows all SQL statements which are executed.
slick.jdbc.JdbcBackend.parameter
Shows bind variable contents (for supported types) of all SQL statements which are executed.
slick.jdbc.JdbcBackend.benchmark
Shows execution times for SQL statements.
slick.jdbc.StatementInvoker.result
Shows the first rows of the result set when a query is executed. Does not apply to streaming results.

Monitoring

When a Database object has the registerMbeans option enabled (see Database.forConfig), Slick registers a JMX management bean of type AsyncExecutorMXBean that provides information about the current workload of the database I/O thread pool and the task queue.

Connection pool implementations may also honor this option and register additional management beans. In particular, the default HikariCP pool implementation does this. See HikariCP Monitoring in the HikariCP documentation for details.

The management bean names are qualified with the poolName from the database configuration, or the config path if the poolName has not been set explicitly.

Example: Including the following configuration options in the database configuration

connectionPool = "HikariCP"
registerMbeans = true
poolName = "myDb"

results in these three management beans being registered:

  • slick:type=AsyncExecutor,name=myDb
  • com.zaxxer.hikari:type=PoolConfig (myDb)
  • com.zaxxer.hikari:type=Pool (myDb)