简体   繁体   中英

Setting environment variables of Sentry dynamically for logback.xml Sentry appender

My app is using slf4j and naturally, I have a logback.xml file. I try to add a Sentry appender to this file. This is my logback.xml file.

<appender name="CONSOLE-INFO" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <target>System.out</target>
        <encoder>
            <pattern>%d %p %c{1.} %m%n</pattern>
        </encoder>
    </appender>
    <appender name="CONSOLE-ERROR" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <target>System.error</target>
        <encoder>
            <pattern>%d %p %c{1.} %m%n%ex{100}</pattern>
        </encoder>
    </appender>
    <appender name="SENTRY" class="io.sentry.logback.SentryAppender">
        <dsn>
            https://...Sentry dsn
        </dsn>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <encoder>
            <pattern>%d %p %c{1.} %m%n%ex{100}</pattern>
        </encoder>
    </appender>
    <logger name="kafkaOrderLogger" level="info" additivity="false">
        <appender-ref ref="CONSOLE-INFO"/>
    </logger>
    <logger name="kafkaOrderErrorLogger" level="error" additivity="false">
        <appender-ref ref="CONSOLE-ERROR"/>
    </logger>
    <logger>
        <appender-ref ref="SENTRY"/>
    </logger>

    <root level="info">
        <appender-ref ref="CONSOLE-INFO"/>
        <appender-ref ref="CONSOLE-ERROR"/>
        <appender-ref ref="SENTRY"/>
    </root>

My app is dockerized before deployment and as part of our ci/cd it is deployed on three different environment, staging pre and production. The problem is I can provide variables only through a property file at the root of my application. This property file will be filled with values based on the deployment environment This means I cannot have a sentry.properties in the resource folder that is filled automatically. What I want is to have Sentry environment set and preferably without touching code as is the whole point of slf4j appenders.

We use environment (shell) variables that are imported automatically by the sentry logback integration.

SENTRY_DSN=https://xxxxxxxx@sentry.io/xxxxxx
SENTRY_TAGS=app:MyApplication,host:$HOSTNAME,project:${CI_PROJECT_NAME},branch:${CI_COMMIT_REF_NAME}
SENTRY_ENVIRONMENT=${CI_COMMIT_REF_NAME}

However there is a big caveat, they are not interpolated.

This happens even if these variables have a value, it will just not get replaced.

Neither $HOSTNAME nor ${CI_COMMIT_REF_NAME} will be resolved. It will result in the string just added verbatim and sent to sentry, as can be seen in the screenshot:

输出结果

When running an application (and it does not matter whether it is Java, Node, Python or using any other officially supported Sentry SDK), the environment variables should be provided by the deployment, not the docker image or the packaged application (jar file, ...).

Where exactly to put them depends on how you are actually running the Docker containers:

  • plain docker run on some host
  • a service as part of a docker-compose setup
  • inside a Kubernetes Deployment
  • ...

I will just describe the first two cases here, since the strategy is the same for other types of deployments and documentation of the respective tooling should be consulted for how to inject environment variables into containers.

docker

If you are running a single Docker container from the command line (or through scripts), then just add the following to the docker run command ( documentation ):

docker run ... -e SENTRY_ENVIRONMENT="<your-env>" ...

docker-compose

...or inside a docker-compose.yml ( documentation ):

...
services:
  my-service:
    ...
    environment:
      SENTRY_ENVIRONMENT: "<your-env>"

A docker-compose setup also supports a file called .env , which can be used to set variables from the outside and use variable substitution .

So you could use the following in your docker-compose.yml instead:

...
services:
  my-service:
    ...
    environment:
      SENTRY_ENVIRONMENT: "${MYENV}"

...and in your .env file:

MYENV=development

Of course, you can also generate a file containing environment variables inside your CI/CD chain and deploy that file with your application, for which you then use docker run --env-file myapp.env ... or the following docker-compose configuration:

...
services:
  my-service:
    ...
    env_file:
      - myapp.env

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM