Java tutorial
/* * Copyright 2016-2018 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.agent.central; import java.util.List; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.collect.Lists; import com.google.common.hash.Hashing; import org.glowroot.common.Constants; import org.glowroot.wire.api.model.AggregateOuterClass.Aggregate; import org.glowroot.wire.api.model.TraceOuterClass.Trace; import static com.google.common.base.Charsets.UTF_8; import static com.google.common.base.Preconditions.checkState; import static java.util.concurrent.TimeUnit.DAYS; class SharedQueryTextLimiter { // if full text sha1 has not been sent in the past day, there's a possibility the full text may // have expired in the central collector and so full text must be sent private final Cache<String, Boolean> sentInThePastDay = CacheBuilder.newBuilder().expireAfterWrite(1, DAYS) .maximumSize(10000).build(); Aggregate.SharedQueryText buildAggregateSharedQueryText(String fullText, List<String> fullTextSha1s) { if (fullText.length() > Constants.AGGREGATE_QUERY_TEXT_TRUNCATE) { String fullTextSha1 = Hashing.sha1().hashString(fullText, UTF_8).toString(); if (sentInThePastDay.getIfPresent(fullTextSha1) == null) { // need to send full text fullTextSha1s.add(fullTextSha1); return Aggregate.SharedQueryText.newBuilder().setFullText(fullText).build(); } else { // ok to just send truncated text return Aggregate.SharedQueryText.newBuilder() .setTruncatedText(fullText.substring(0, Constants.AGGREGATE_QUERY_TEXT_TRUNCATE)) .setFullTextSha1(fullTextSha1).build(); } } else { return Aggregate.SharedQueryText.newBuilder().setFullText(fullText).build(); } } Trace.SharedQueryText buildTraceSharedQueryText(String fullText, List<String> fullTextSha1s) { if (fullText.length() > 2 * Constants.TRACE_QUERY_TEXT_TRUNCATE) { String fullTextSha1 = Hashing.sha1().hashString(fullText, UTF_8).toString(); if (sentInThePastDay.getIfPresent(fullTextSha1) == null) { fullTextSha1s.add(fullTextSha1); // need to send full text return Trace.SharedQueryText.newBuilder().setFullText(fullText).build(); } else { // ok to just send truncated text return Trace.SharedQueryText.newBuilder() .setTruncatedText(fullText.substring(0, Constants.TRACE_QUERY_TEXT_TRUNCATE)) .setTruncatedEndText(fullText.substring( fullText.length() - Constants.TRACE_QUERY_TEXT_TRUNCATE, fullText.length())) .setFullTextSha1(fullTextSha1).build(); } } else { return Trace.SharedQueryText.newBuilder().setFullText(fullText).build(); } } List<Trace.SharedQueryText> reduceTracePayloadWherePossible(List<Trace.SharedQueryText> sharedQueryTexts) { List<Trace.SharedQueryText> updatedSharedQueryTexts = Lists.newArrayList(); for (Trace.SharedQueryText sharedQueryText : sharedQueryTexts) { // local collection always passes in full text checkState(sharedQueryText.getTruncatedText().isEmpty()); checkState(sharedQueryText.getTruncatedEndText().isEmpty()); checkState(sharedQueryText.getFullTextSha1().isEmpty()); String fullText = sharedQueryText.getFullText(); if (fullText.length() > 2 * Constants.TRACE_QUERY_TEXT_TRUNCATE) { String fullTextSha1 = Hashing.sha1().hashString(fullText, UTF_8).toString(); if (sentInThePastDay.getIfPresent(fullTextSha1) == null) { // need to send full text updatedSharedQueryTexts.add(sharedQueryText); } else { // ok to just send truncated text updatedSharedQueryTexts.add(Trace.SharedQueryText.newBuilder() .setTruncatedText(fullText.substring(0, Constants.TRACE_QUERY_TEXT_TRUNCATE)) .setTruncatedEndText(fullText.substring( fullText.length() - Constants.TRACE_QUERY_TEXT_TRUNCATE, fullText.length())) .setFullTextSha1(fullTextSha1).build()); } } else { updatedSharedQueryTexts.add(sharedQueryText); } } return updatedSharedQueryTexts; } void onSuccessfullySentToCentralCollector(String fullTextSha1) { sentInThePastDay.put(fullTextSha1, true); } }