All Downloads are FREE. Search and download functionalities are using the official Maven repository.

zipkin2.storage.cassandra.CassandraStorage Maven / Gradle / Ivy

There is a newer version: 3.4.2
Show newest version
/*
 * Copyright The OpenZipkin Authors
 * SPDX-License-Identifier: Apache-2.0
 */
package zipkin2.storage.cassandra;

import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.auth.AuthProvider;
import com.datastax.oss.driver.api.core.auth.ProgrammaticPlainTextAuthProvider;
import com.datastax.oss.driver.api.core.config.DriverOption;
import java.util.Map;
import java.util.Set;
import zipkin2.Call;
import zipkin2.CheckResult;
import zipkin2.internal.ClosedComponentException;
import zipkin2.internal.Nullable;
import zipkin2.storage.AutocompleteTags;
import zipkin2.storage.ServiceAndSpanNames;
import zipkin2.storage.SpanConsumer;
import zipkin2.storage.SpanStore;
import zipkin2.storage.StorageComponent;
import zipkin2.storage.Traces;
import zipkin2.storage.cassandra.internal.call.ResultSetFutureCall;

/**
 * CQL3 implementation of zipkin storage.
 *
 * 

Queries are logged to the category "com.datastax.oss.driver.api.core.cql.QueryLogger" when * debug or trace is enabled via SLF4J. Trace level includes bound values. * *

Schema is installed by default from "/zipkin2-schema.cql" * *

When {@link StorageComponent.Builder#strictTraceId(boolean)} is disabled, span and index data * are uniformly written with 64-bit trace ID length. When retrieving data, an extra "trace_id_high" * field clarifies if a 128-bit trace ID was sent. */ public final class CassandraStorage extends StorageComponent { // @FunctionalInterface, except safe for lower language levels public interface SessionFactory { SessionFactory DEFAULT = new DefaultSessionFactory(); CqlSession create(CassandraStorage storage); } public static Builder newBuilder() { return new Builder(); } public static final class Builder extends CassandraStorageBuilder { Builder() { super(Schema.DEFAULT_KEYSPACE); } /** Keyspace to store span and index data. Defaults to "zipkin2" */ @Override public Builder keyspace(String keyspace) { return super.keyspace(keyspace); } /** * Ensures that schema exists, if enabled tries to execute: *

    *
  1. io.zipkin.zipkin2:zipkin-storage-cassandra/zipkin2-schema.cql
  2. *
  3. io.zipkin.zipkin2:zipkin-storage-cassandra/zipkin2-indexes.cql
  4. *
* Defaults to true. */ @Override public Builder ensureSchema(boolean ensureSchema) { return super.ensureSchema(ensureSchema); } @Override public CassandraStorage build() { return new CassandraStorage(this); } } final boolean strictTraceId, searchEnabled; final Set autocompleteKeys; final int autocompleteTtl, autocompleteCardinality; final String contactPoints, localDc; final Map poolingOptions; @Nullable final AuthProvider authProvider; final boolean useSsl; final boolean sslHostnameValidation; final String keyspace; final int maxTraceCols, indexFetchMultiplier; final LazySession session; CassandraStorage(CassandraStorageBuilder builder) { // Assign generic configuration for all storage components this.strictTraceId = builder.strictTraceId; this.searchEnabled = builder.searchEnabled; this.autocompleteKeys = builder.autocompleteKeys; this.autocompleteTtl = builder.autocompleteTtl; this.autocompleteCardinality = builder.autocompleteCardinality; // Assign configuration used to create a session this.contactPoints = builder.contactPoints; this.localDc = builder.localDc; this.poolingOptions = builder.poolingOptions(); if (builder.username != null) { this.authProvider = new ProgrammaticPlainTextAuthProvider(builder.username, builder.password); } else { this.authProvider = null; } this.useSsl = builder.useSsl; this.sslHostnameValidation = builder.sslHostnameValidation; this.keyspace = builder.keyspace; // Assign configuration used to control queries this.maxTraceCols = builder.maxTraceCols; this.indexFetchMultiplier = builder.indexFetchMultiplier; this.session = new LazySession(this, builder.sessionFactory, builder.ensureSchema); } /** close is typically called from a different thread */ volatile boolean closeCalled; volatile CassandraSpanConsumer spanConsumer; volatile CassandraSpanStore spanStore; volatile CassandraAutocompleteTags tagStore; /** Lazy initializes or returns the session in use by this storage component. */ CqlSession session() { return session.get(); } Schema.Metadata metadata() { return session.metadata(); } /** {@inheritDoc} Memoized in order to avoid re-preparing statements */ @Override public SpanStore spanStore() { if (spanStore == null) { synchronized (this) { if (spanStore == null) { spanStore = new CassandraSpanStore(this); } } } return spanStore; } @Override public Traces traces() { return (Traces) spanStore(); } @Override public ServiceAndSpanNames serviceAndSpanNames() { return (ServiceAndSpanNames) spanStore(); } @Override public AutocompleteTags autocompleteTags() { if (tagStore == null) { synchronized (this) { if (tagStore == null) { tagStore = new CassandraAutocompleteTags(this); } } } return tagStore; } // Memoized in order to avoid re-preparing statements @Override public SpanConsumer spanConsumer() { if (spanConsumer == null) { synchronized (this) { if (spanConsumer == null) { spanConsumer = new CassandraSpanConsumer(this); } } } return spanConsumer; } @Override public boolean isOverCapacity(Throwable e) { return ResultSetFutureCall.isOverCapacity(e); } @Override public String toString() { return "CassandraStorage{contactPoints=" + contactPoints + ", keyspace=" + keyspace + "}"; } @Override public CheckResult check() { if (closeCalled) throw new ClosedComponentException(); try { session.healthCheck(); } catch (Throwable e) { Call.propagateIfFatal(e); return CheckResult.failed(e); } return CheckResult.OK; } @Override public void close() { if (closeCalled) return; session.close(); closeCalled = true; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy