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

io.helidon.tracing.config.ComponentTracingConfig Maven / Gradle / Ivy

/*
 * Copyright (c) 2019, 2023 Oracle and/or its affiliates.
 *
 * 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 io.helidon.tracing.config;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import io.helidon.common.config.Config;

/**
 * A component is a single "layer" of the application that can trace.
 * Component examples:
 * 
    *
  • web-server: webServer adds the root tracing span + two additional spans (content-read and content-write)
  • *
  • security: security adds the overall request security span, a span for authentication ("security:atn"), a span for * authorization "security:atz", and a span for response processing ("security:response")
  • *
  • jax-rs: JAX-RS integration adds spans for overall resource invocation
  • *
*/ public abstract class ComponentTracingConfig extends Traceable { /** * Disabled component - all subsequent calls return disabled spans and logs. */ public static final ComponentTracingConfig DISABLED = ComponentTracingConfig.builder("disabled").enabled(false).build(); /** * Enabled component - all subsequent calls return enabled spans and logs. */ public static final ComponentTracingConfig ENABLED = ComponentTracingConfig.builder("enabled").build(); /** * A new named component. * * @param name name of the component */ protected ComponentTracingConfig(String name) { super(name); } /** * Merge configuration of two traced components. This enabled hierarchical configuration * with common, default configuration in one traced component and override in another. * * @param older the older configuration with "defaults" * @param newer the newer configuration to override defaults in older * @return merged component */ static ComponentTracingConfig merge(ComponentTracingConfig older, ComponentTracingConfig newer) { return new ComponentTracingConfig(newer.name()) { @Override public Optional getSpan(String spanName) { if (!enabled()) { return Optional.of(SpanTracingConfig.DISABLED); } Optional newSpan = newer.getSpan(spanName); Optional oldSpan = older.getSpan(spanName); // both configured if (newSpan.isPresent() && oldSpan.isPresent()) { return Optional.of(SpanTracingConfig.merge(oldSpan.get(), newSpan.get())); } // only newer if (newSpan.isPresent()) { return newSpan; } return oldSpan; } @Override public Optional isEnabled() { return newer.isEnabled() .or(older::isEnabled); } }; } /** * Get a traced span configuration for a named span. * * @param spanName name of the span in this component * @return configuration of that span if present */ protected abstract Optional getSpan(String spanName); /** * Get a traced span configuration for a named span. * * @param spanName name of a span in this component * @return configuration of the span, or enabled configuration if not configured * @see #span(String, boolean) */ public SpanTracingConfig span(String spanName) { return span(spanName, true); } /** * Get a traced span configuration for a named span. * * @param spanName name of a span in this component * @param enabledByDefault whether the result is enabled if a configuration is not present * @return configuration of the span, or a span configuration enabled or disabled depending on {@code enabledByDefault} if * not configured */ public SpanTracingConfig span(String spanName, boolean enabledByDefault) { if (enabled()) { return getSpan(spanName).orElseGet(() -> enabledByDefault ? SpanTracingConfig.ENABLED : SpanTracingConfig.DISABLED); } return SpanTracingConfig.DISABLED; } /** * Fluent API builder for traced component. * * @param name the name of the component * @return a new builder instance */ public static Builder builder(String name) { return new Builder(name); } /** * Create a new traced component configuration from {@link Config}. * * @param name name of the component * @param config config for a new component * @return a new traced component configuration */ public static ComponentTracingConfig create(String name, Config config) { return builder(name) .config(config) .build(); } /** * Fluent API builder for {@link ComponentTracingConfig}. */ public static final class Builder implements io.helidon.common.Builder { private final Map tracedSpans = new HashMap<>(); private Optional enabled = Optional.empty(); private final String name; private Builder(String name) { this.name = name; } @Override public ComponentTracingConfig build() { // immutability final Optional finalEnabled = enabled; final Map finalSpans = new HashMap<>(tracedSpans); return new ComponentTracingConfig(name) { @Override public Optional getSpan(String spanName) { if (enabled.orElse(true)) { return Optional.ofNullable(finalSpans.get(spanName)); } else { return Optional.of(SpanTracingConfig.DISABLED); } } @Override public Optional isEnabled() { return finalEnabled; } }; } /** * Update this builder from {@link io.helidon.common.config.Config}. * * @param config configuration of a traced component * @return updated builder instance */ public Builder config(Config config) { config.get("enabled").asBoolean().ifPresent(this::enabled); config.get("spans").asNodeList().ifPresent(spanConfigList -> { spanConfigList.forEach(spanConfig -> { // span name is mandatory addSpan(SpanTracingConfig.create(spanConfig.get("name").asString().get(), spanConfig)); }); }); return this; } /** * Add a new traced span configuration. * * @param span configuration of a traced span * @return updated builder instance */ public Builder addSpan(SpanTracingConfig span) { this.tracedSpans.put(span.name(), span); return this; } /** * Configure whether this component is enabled or disabled. * * @param enabled if disabled, all spans and logs will be disabled * @return updated builder instance */ public Builder enabled(boolean enabled) { this.enabled = Optional.of(enabled); return this; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy