zipkin.autoconfigure.storage.mysql.brave.TraceZipkinMySQLStorageAutoConfiguration.java Source code

Java tutorial

Introduction

Here is the source code for zipkin.autoconfigure.storage.mysql.brave.TraceZipkinMySQLStorageAutoConfiguration.java

Source

/**
 * Copyright 2015-2017 The OpenZipkin Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package zipkin.autoconfigure.storage.mysql.brave;

import com.github.kristofa.brave.Brave;
import com.github.kristofa.brave.ServerSpan;
import com.github.kristofa.brave.ServerSpanState;
import com.twitter.zipkin.gen.Endpoint;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.concurrent.Executor;
import org.jooq.ExecuteContext;
import org.jooq.ExecuteListenerProvider;
import org.jooq.impl.DefaultExecuteListener;
import org.jooq.impl.DefaultExecuteListenerProvider;
import org.jooq.tools.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import zipkin.autoconfigure.storage.mysql.ZipkinMySQLStorageProperties;

import static zipkin.TraceKeys.SQL_QUERY;

/** Sets up the MySQL tracing in Brave as an initialization. */
@ConditionalOnBean(Brave.class)
@ConditionalOnProperty(name = "zipkin.storage.type", havingValue = "mysql")
@Configuration
public class TraceZipkinMySQLStorageAutoConfiguration extends DefaultExecuteListener {

    @Autowired
    ZipkinMySQLStorageProperties mysql;

    @Bean
    ExecuteListenerProvider tracingExecuteListenerProvider() {
        return new DefaultExecuteListenerProvider(this);
    }

    @Bean
    @ConditionalOnMissingBean(Executor.class)
    public Executor executor(ServerSpanState serverState) {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setThreadNamePrefix("MySQLStorage-");
        executor.initialize();
        return command -> {
            ServerSpan currentSpan = serverState.getCurrentServerSpan();
            executor.execute(() -> {
                serverState.setCurrentServerSpan(currentSpan);
                command.run();
            });
        };
    }

    /** Attach the IP of the remote datasource, knowing that DNS may invalidate this */
    @Bean
    @Qualifier("mysql")
    Endpoint mysql() throws UnknownHostException {
        int ipv4 = ByteBuffer.wrap(InetAddress.getByName(mysql.getHost()).getAddress()).getInt();
        return Endpoint.builder().serviceName("mysql").ipv4(ipv4).port(mysql.getPort()).build();
    }

    @Autowired
    @Lazy // to unwind a circular dep: we are tracing the storage used by brave
    Brave brave;
    @Autowired
    @Qualifier("mysql")
    Endpoint mysqlEndpoint;

    @Override
    public void renderEnd(ExecuteContext ctx) {
        // Only join traces, don't start them. This prevents LocalCollector's thread from amplifying.
        if (brave.serverSpanThreadBinder().getCurrentServerSpan() == null
                || brave.serverSpanThreadBinder().getCurrentServerSpan().getSpan() == null) {
            return;
        }

        brave.clientTracer().startNewSpan(ctx.type().toString().toLowerCase());
        String[] batchSQL = ctx.batchSQL();
        if (!StringUtils.isBlank(ctx.sql())) {
            brave.clientTracer().submitBinaryAnnotation(SQL_QUERY, ctx.sql());
        } else if (batchSQL.length > 0 && batchSQL[batchSQL.length - 1] != null) {
            brave.clientTracer().submitBinaryAnnotation(SQL_QUERY, StringUtils.join(batchSQL, '\n'));
        }
        brave.clientTracer().setClientSent(mysqlEndpoint);
    }

    @Override
    public void executeEnd(ExecuteContext ctx) {
        if (brave.serverSpanThreadBinder().getCurrentServerSpan() == null
                || brave.serverSpanThreadBinder().getCurrentServerSpan().getSpan() == null) {
            return;
        }
        brave.clientTracer().setClientReceived();
    }
}