Skip to main content

Logging Configuration

Constellation Engine uses Logback (SLF4J) for structured logging. This guide covers configuration strategies for different deployment scenarios.


Quick Start​

Enable Debug Logging (Development)​

export CONSTELLATION_LOG_LEVEL=DEBUG
make server

You'll now see:

  • DEBUG logs from compilation cache hits/misses
  • INFO logs for pipeline execution lifecycle
  • WARN logs for module timeouts
  • ERROR logs with full stacktraces for failures

Run with Default Logging (Production)​

make server

Default behavior:

  • INFO level for Constellation packages only
  • WARN level for everything else (suppresses noise)
  • Only important events logged

Environment Variables​

CONSTELLATION_LOG_LEVEL​

Controls the log level for all Constellation packages.

ValueBehaviorUse Case
DEBUGAll debug messages visibleDevelopment, troubleshooting
INFONormal operations (default)Production, testing
WARNWarnings and errors onlyMinimal logging
ERRORErrors onlySilent operation

Example:

CONSTELLATION_LOG_LEVEL=DEBUG make server    # Development
CONSTELLATION_LOG_LEVEL=INFO make server # Production (default)

What Gets Logged​

Module Execution (Runtime)​

When a module executes, the runtime logs:

EventLevelMessageWhen
TimeoutWARNModule 'X' timed out after 30sModule doesn't respond in time
FailureERRORModule 'X' failed: connection refusedModule throws exception

Example output:

14:32:01.234 [pool-1-thread-2] WARN  io.constellation.Runtime - Module 'FetchUser' timed out after 30s
14:32:02.456 [pool-1-thread-3] ERROR io.constellation.Runtime - Module 'ValidateEmail' failed: Invalid format

Pipeline Execution (ConstellationImpl)​

When you run a pipeline, you see:

EventLevelMessageInformation
StartINFOExecuting pipeline 'MyPipeline' [abc123def456]Pipeline name + hash prefix
CompleteINFOPipeline 'MyPipeline' [abc123def456] completed: success in 1234msStatus + elapsed time

Example output:

14:32:00.000 [http-event-loop-1] INFO io.constellation.impl.ConstellationImpl - Executing pipeline 'TextProcessor' [a7f9e2c1d5]
14:32:01.234 [http-event-loop-1] INFO io.constellation.impl.ConstellationImpl - Pipeline 'TextProcessor' [a7f9e2c1d5] completed: success in 1234ms

Compilation (LangCompiler)​

When the compiler processes source code:

EventLevelMessageInformation
FailureERRORCompilation failed for 'MyPipeline': 2 error(s) — Type mismatch; Unknown moduleError count + details

Example output:

14:32:00.500 [http-event-loop-2] ERROR io.constellation.lang.LangCompiler - Compilation failed for 'test': 2 error(s) — Type mismatch in Add(text, 10); Module 'UndefinedModule' not found

Cache Operations (CachingLangCompiler)​

When compilation caching is active and CONSTELLATION_LOG_LEVEL=DEBUG:

EventLevelMessageInformation
Cache HitDEBUGCompilation cache hit for 'MyPipeline' [src:a7f9e2c1]Avoids recompilation
Cache MissDEBUGCompilation cache miss for 'MyPipeline' — compilingCache miss details

Example output (DEBUG only):

14:32:00.001 [http-event-loop-3] DEBUG io.constellation.lang.CachingLangCompiler - Compilation cache hit for 'test' [src:abc12345]
14:32:00.001 [http-event-loop-3] DEBUG io.constellation.lang.CachingLangCompiler - Compilation cache miss for 'new-script' — compiling

Configuration Strategies​

Development Setup​

Goal: See everything for debugging

export CONSTELLATION_LOG_LEVEL=DEBUG
make server 2>&1 | tee dev.log

This gives you:

  • Full stacktraces on errors
  • Cache hit/miss visibility
  • Pipeline timing
  • Module-level diagnostics

Production Setup​

Goal: Minimal logging, fast performance

export CONSTELLATION_LOG_LEVEL=WARN
make server

Or, start the server and redirect logs to a file:

make server 2>> constellation.log &

This logs only:

  • Critical errors (module failures, compilation errors)
  • Warnings (timeouts)
  • No debug spam

Testing Setup​

Goal: Normal logging during test runs

export CONSTELLATION_LOG_LEVEL=INFO
make test

For Library Users​

If you're using Constellation Engine as a library in your Scala project:

1. Add Logback Dependency​

// build.sbt
libraryDependencies ++= Seq(
"org.slf4j" % "slf4j-api" % "2.0.7",
"ch.qos.logback" % "logback-classic" % "1.4.11"
)

2. Create Your Own logback.xml​

Place this in src/main/resources/logback.xml:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<!-- Constellation packages - adjust as needed -->
<logger name="io.constellation" level="${CONSTELLATION_LOG_LEVEL:-INFO}" />

<!-- Suppress http4s noise -->
<logger name="org.http4s.ember" level="WARN" />

<!-- Root logger -->
<root level="WARN">
<appender-ref ref="CONSOLE" />
</root>
</configuration>

3. Use in Your Code​

import org.typelevel.log4cats.Logger
import org.typelevel.log4cats.slf4j.Slf4jLogger

val constellation = ConstellationImpl.init

val myPipeline = """
in text: String
result = Uppercase(text)
out result
"""

for {
logger <- Slf4jLogger.create[IO]
compiled <- constellation.langCompiler.compileIO(myPipeline, "MyPipeline")
result <- compiled match {
case Right(output) =>
logger.info("Compilation succeeded") *> IO.pure(output)
case Left(errors) =>
logger.error(s"Compilation failed: ${errors.size} errors") *>
IO.raiseError(new Exception(s"Failed: ${errors.map(_.message).mkString("; ")}"))
}
} yield result

4. Control Logging via Environment​

Library users can control logging at runtime:

# For debugging
CONSTELLATION_LOG_LEVEL=DEBUG java -jar myapp.jar

# For production
CONSTELLATION_LOG_LEVEL=WARN java -jar myapp.jar

Advanced Configuration​

Production Logging with File Rotation​

For long-running servers, use rolling file appenders:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- Console for immediate visibility -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<!-- File with rolling (rotate daily or at 100MB) -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/constellation.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- Rotate daily or when file reaches 100MB -->
<fileNamePattern>logs/constellation.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory> <!-- Keep 30 days -->
</rollingPolicy>
<encoder>
<pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<!-- Constellation at INFO in production -->
<logger name="io.constellation" level="INFO" />
<logger name="org.http4s.ember" level="WARN" />

<!-- Root to FILE, console for emergencies -->
<root level="WARN">
<appender-ref ref="FILE" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>

JSON Structured Logging (Optional)​

For log aggregation (ELK, Datadog, Splunk):

<appender name="LOGSTASH" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/constellation.json</file>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"environment":"production","service":"constellation"}</customFields>
</encoder>
<!-- rolling policy same as above -->
</appender>

Troubleshooting​

No logs appearing?​

  1. Check environment variable:

    echo $CONSTELLATION_LOG_LEVEL
  2. Verify logback.xml exists and is on classpath:

    jar tf constellation-engine.jar | grep logback.xml
  3. Check if logs are being suppressed:

    • Root logger level might be too high (set to WARN or ERROR)
    • Try CONSTELLATION_LOG_LEVEL=DEBUG explicitly

Logs too verbose?​

  1. Reduce to WARN:

    export CONSTELLATION_LOG_LEVEL=WARN
  2. Suppress specific loggers in logback.xml:

    <logger name="org.http4s" level="ERROR" />
    <logger name="org.typelevel" level="WARN" />

Performance impact?​

  • DEBUG logging adds ~5-10% overhead
  • INFO/WARN logging is negligible (<1%)
  • Use INFO in production, DEBUG only for troubleshooting