
org.glowroot.common.config.InstrumentationConfig Maven / Gradle / Ivy
/*
* Copyright 2013-2015 the original author or 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 org.glowroot.common.config;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.annotation.Nullable;
import org.glowroot.agent.shaded.fasterxml.jackson.annotation.JsonIgnore;
import org.glowroot.agent.shaded.fasterxml.jackson.annotation.JsonInclude;
import org.glowroot.agent.shaded.fasterxml.jackson.annotation.JsonInclude.Include;
import org.glowroot.agent.shaded.google.common.base.Charsets;
import org.glowroot.agent.shaded.google.common.collect.ImmutableList;
import org.glowroot.agent.shaded.google.common.collect.Lists;
import org.glowroot.agent.shaded.google.common.hash.Hasher;
import org.glowroot.agent.shaded.google.common.hash.Hashing;
import org.immutables.value.Value;
@Value.Immutable
public abstract class InstrumentationConfig {
public abstract String className();
@Value.Default
@JsonInclude(value = Include.NON_EMPTY)
public String declaringClassName() {
return "";
}
public abstract String methodName();
// empty methodParameterTypes means match no-arg methods only
public abstract ImmutableList methodParameterTypes();
@Value.Default
@JsonInclude(value = Include.NON_EMPTY)
public String methodReturnType() {
return "";
}
// currently unused, but will have a purpose someday, e.g. to capture all public methods
@JsonInclude(value = Include.NON_EMPTY)
public abstract ImmutableList methodModifiers();
public abstract CaptureKind captureKind();
@Value.Default
@JsonInclude(value = Include.NON_EMPTY)
public String transactionType() {
return "";
}
@Value.Default
@JsonInclude(value = Include.NON_EMPTY)
public String transactionNameTemplate() {
return "";
}
@Value.Default
@JsonInclude(value = Include.NON_EMPTY)
public String transactionUserTemplate() {
return "";
}
@JsonInclude(value = Include.NON_EMPTY)
public abstract Map transactionAttributeTemplates();
// need to write zero since it is treated different from null
@JsonInclude(value = Include.NON_NULL)
public abstract @Nullable Integer transactionSlowThresholdMillis();
@Value.Default
@JsonInclude(value = Include.NON_EMPTY)
public String traceEntryMessageTemplate() {
return "";
}
// need to write zero since it is treated different from null
@JsonInclude(value = Include.NON_NULL)
public abstract @Nullable Integer traceEntryStackThresholdMillis();
@Value.Default
@JsonInclude(value = Include.NON_EMPTY)
public boolean traceEntryCaptureSelfNested() {
return false;
}
@Value.Default
@JsonInclude(value = Include.NON_EMPTY)
public String timerName() {
return "";
}
// this is only for plugin authors (to be used in glowroot.plugin.json)
@Value.Default
@JsonInclude(value = Include.NON_EMPTY)
public String enabledProperty() {
return "";
}
// this is only for plugin authors (to be used in glowroot.plugin.json)
@Value.Default
@JsonInclude(value = Include.NON_EMPTY)
public String traceEntryEnabledProperty() {
return "";
}
// this uses Guava's Hashing instead of json/md5 "cheat" like other configs, because it is used
// by weaving, and using json/md5 would require pre-initialization tons of Jackson classes
// see PreInitializeWeavingClassesTest.java
@JsonIgnore
@Value.Derived
public String version() {
Hasher hasher = Hashing.md5().newHasher()
.putString(className(), Charsets.UTF_8)
.putString(declaringClassName(), Charsets.UTF_8)
.putString(methodName(), Charsets.UTF_8)
.putInt(methodParameterTypes().size());
for (String methodParameterType : methodParameterTypes()) {
hasher.putString(methodParameterType, Charsets.UTF_8);
}
hasher.putString(methodReturnType(), Charsets.UTF_8);
hasher.putInt(methodModifiers().size());
for (MethodModifier methodModifier : methodModifiers()) {
hasher.putString(methodModifier.name(), Charsets.UTF_8);
}
hasher.putString(captureKind().name(), Charsets.UTF_8);
hasher.putString(transactionType(), Charsets.UTF_8);
hasher.putString(transactionNameTemplate(), Charsets.UTF_8);
hasher.putString(transactionUserTemplate(), Charsets.UTF_8);
hasher.putInt(transactionAttributeTemplates().size());
for (Entry entry : transactionAttributeTemplates().entrySet()) {
hasher.putString(entry.getKey(), Charsets.UTF_8);
hasher.putString(entry.getValue(), Charsets.UTF_8);
}
Integer transactionSlowThresholdMillis = transactionSlowThresholdMillis();
if (transactionSlowThresholdMillis != null) {
hasher.putInt(transactionSlowThresholdMillis);
}
hasher.putString(traceEntryMessageTemplate(), Charsets.UTF_8);
Integer traceEntryStackThresholdMillis = traceEntryStackThresholdMillis();
if (traceEntryStackThresholdMillis != null) {
hasher.putInt(traceEntryStackThresholdMillis);
}
hasher.putBoolean(traceEntryCaptureSelfNested());
hasher.putString(timerName(), Charsets.UTF_8);
hasher.putString(enabledProperty(), Charsets.UTF_8);
hasher.putString(traceEntryEnabledProperty(), Charsets.UTF_8);
return hasher.hash().toString();
}
@JsonIgnore
@Value.Derived
public boolean isTimerOrGreater() {
return captureKind() == CaptureKind.TIMER || captureKind() == CaptureKind.TRACE_ENTRY
|| captureKind() == CaptureKind.TRANSACTION;
}
@JsonIgnore
@Value.Derived
public boolean isTraceEntryOrGreater() {
return captureKind() == CaptureKind.TRACE_ENTRY || captureKind() == CaptureKind.TRANSACTION;
}
@JsonIgnore
@Value.Derived
public boolean isTransaction() {
return captureKind() == CaptureKind.TRANSACTION;
}
@JsonIgnore
@Value.Derived
public ImmutableList validationErrors() {
List errors = Lists.newArrayList();
if (className().isEmpty()) {
errors.add("className is empty");
}
if (methodName().isEmpty()) {
errors.add("methodName is empty");
}
if (isTimerOrGreater() && timerName().isEmpty()) {
errors.add("timerName is empty");
}
if (captureKind() == CaptureKind.TRACE_ENTRY && traceEntryMessageTemplate().isEmpty()) {
errors.add("traceEntryMessageTemplate is empty");
}
if (isTransaction() && transactionType().isEmpty()) {
errors.add("transactionType is empty");
}
if (isTransaction() && transactionNameTemplate().isEmpty()) {
errors.add("transactionNameTemplate is empty");
}
if (!timerName().matches("[a-zA-Z0-9 ]*")) {
errors.add("timerName contains invalid characters: " + timerName());
}
return ImmutableList.copyOf(errors);
}
public enum MethodModifier {
PUBLIC, STATIC, NOT_STATIC;
}
public enum CaptureKind {
TRANSACTION, TRACE_ENTRY, TIMER, OTHER
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy