Skip to content

Commit

Permalink
[#6609] Add UriStatHistogramSchema
Browse files Browse the repository at this point in the history
- Add Schema
- Add AsyncQueueingStorage
  • Loading branch information
koo-taejin committed Nov 30, 2020
1 parent 77197b9 commit af0a3f2
Show file tree
Hide file tree
Showing 14 changed files with 504 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ private static Properties loadProperties(String pinpointConfigFileName) throws I
private int customMetricLimitSize = 10;

private boolean uriStatEnable = false;
private int uriStatCollectInterval = 60 * 1000;

public DefaultProfilerConfig() {
this.properties = new Properties();
Expand Down Expand Up @@ -426,6 +427,11 @@ public boolean isUriStatEnable() {
return uriStatEnable;
}

@Override
public int getUriStatCollectInterval() {
return uriStatCollectInterval;
}

// for test
void readPropertyValues() {

Expand Down Expand Up @@ -526,6 +532,7 @@ void readPropertyValues() {
this.customMetricLimitSize = readInt("profiler.custommetric.limit.size", 10);

this.uriStatEnable = readBoolean("profiler.uri.stat.enable", false);
this.uriStatCollectInterval = readInt("profiler.uri.stat.collect.interval", 60000);

logger.info("configuration loaded successfully.");
}
Expand Down Expand Up @@ -679,7 +686,8 @@ public String toString() {
sb.append(", applicationNamespace='").append(applicationNamespace).append('\'');
sb.append(", customMetricEnable=").append(customMetricEnable).append('\'');
sb.append(", customMetricLimitSize=").append(customMetricLimitSize).append('\'');
sb.append(", uriStatEnable=").append(uriStatEnable);
sb.append(", uriStatEnable=").append(uriStatEnable).append('\'');
sb.append(", uriStatCollectInterval=").append(uriStatCollectInterval);
sb.append('}');
return sb.toString();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ public interface ProfilerConfig {

boolean isUriStatEnable();

int getUriStatCollectInterval();

String readString(String propertyName, String defaultValue);

String readString(String propertyName, String defaultValue, ValueResolver valueResolver);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig;
import com.navercorp.pinpoint.common.util.Assert;
import com.navercorp.pinpoint.profiler.context.storage.AsyncQueueingUriStatStorage;
import com.navercorp.pinpoint.profiler.context.storage.DisabledUriStatStorage;
import com.navercorp.pinpoint.profiler.context.storage.UriStatStorage;

Expand All @@ -29,6 +30,8 @@
*/
public class UriStatStorageProvider implements Provider<UriStatStorage> {

private static final String URI_STAT_STORAGE_EXECUTOR_NAME = "Pinpoint-StatStorageExecutor";

private final ProfilerConfig profilerConfig;

@Inject
Expand All @@ -39,8 +42,7 @@ public UriStatStorageProvider(ProfilerConfig profilerConfig) {
@Override
public UriStatStorage get() {
if (profilerConfig.isUriStatEnable()) {
// TO DO : have to change
return new DisabledUriStatStorage();
return new AsyncQueueingUriStatStorage(5012, profilerConfig.getUriStatCollectInterval(), URI_STAT_STORAGE_EXECUTOR_NAME);
} else {
return new DisabledUriStatStorage();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ public void record(T request, String rawUri, boolean status, long startTime, lon
String uri = uriExtractor.getUri(request, rawUri);
if (uri == null) {
logger.warn("can not extract uri. request:{}, rawUri:{}", request, rawUri);
return;
}

final UriStatInfo uriStatInfo = new UriStatInfo(uri, status, endTime, endTime - startTime);
uriStatStorage.store(uriStatInfo);
uriStatStorage.store(uri, status, endTime - startTime);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Copyright 2020 NAVER Corp.
*
* 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 com.navercorp.pinpoint.profiler.context.storage;

import com.navercorp.pinpoint.common.util.Assert;
import com.navercorp.pinpoint.common.util.CollectionUtils;
import com.navercorp.pinpoint.profiler.monitor.metric.uri.AgentUriStatData;
import com.navercorp.pinpoint.profiler.monitor.metric.uri.UriStatInfo;
import com.navercorp.pinpoint.profiler.sender.AsyncQueueingExecutor;
import com.navercorp.pinpoint.profiler.sender.AsyncQueueingExecutorListener;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;

/**
* @author Taejin Koo
*/
public class AsyncQueueingUriStatStorage extends AsyncQueueingExecutor<UriStatInfo> implements UriStatStorage {

private static final Logger LOGGER = LoggerFactory.getLogger(AsyncQueueingUriStatStorage.class);

private final ExecutorListener executorListener;

public AsyncQueueingUriStatStorage(int queueSize, int collectInterval, String executorName) {
this(queueSize, executorName, new ExecutorListener(collectInterval));
}

private AsyncQueueingUriStatStorage(int queueSize, String executorName, ExecutorListener executorListener) {
super(queueSize, executorName, executorListener);
this.executorListener = executorListener;
}

@Override
public void store(String uri, boolean status, long elapsedTime) {
Assert.requireNonNull(uri, "uri");
UriStatInfo uriStatInfo = new UriStatInfo(uri, status, elapsedTime);
execute(uriStatInfo);
}

@Override
protected void pollTimeout(long timeout) {
executorListener.executePollTimeout();
}

private static class ExecutorListener implements AsyncQueueingExecutorListener<UriStatInfo> {

private AgentUriStatData agentUriStatData;
private int collectInterval;

public ExecutorListener(int collectInterval) {
Assert.isTrue(collectInterval > 0, "collectInterval must be ' > 0'");
this.collectInterval = collectInterval;
}

@Override
public void execute(Collection<UriStatInfo> messageList) {
final long currentBaseTimestamp = getBaseTimestamp();
checkAndFlushOldData(currentBaseTimestamp);

AgentUriStatData agentUriStatData = getUriStatBatchBuilder(currentBaseTimestamp);

Object[] dataList = messageList.toArray();
for (int i = 0; i < CollectionUtils.nullSafeSize(messageList); i++) {
try {
agentUriStatData.add((UriStatInfo) dataList[i]);
} catch (Throwable th) {
LOGGER.warn("Unexpected Error. Cause:{}", th.getMessage(), th);
}
}
}

@Override
public void execute(UriStatInfo message) {
long currentBaseTimestamp = getBaseTimestamp();
checkAndFlushOldData(currentBaseTimestamp);

AgentUriStatData agentUriStatData = getUriStatBatchBuilder(currentBaseTimestamp);
agentUriStatData.add(message);
}

public void executePollTimeout() {
long currentBaseTimestamp = getBaseTimestamp();
checkAndFlushOldData(currentBaseTimestamp);
}

private long getBaseTimestamp() {
long currentTimeMillis = System.currentTimeMillis();
long timestamp = currentTimeMillis - (currentTimeMillis % collectInterval);
return timestamp;
}

private boolean checkAndFlushOldData(long currentBaseTimestamp) {
if (agentUriStatData == null) {
return false;
}

if (currentBaseTimestamp > agentUriStatData.getBaseTimestamp()) {
// TODO FLUSH
agentUriStatData = null;
return true;
}
return false;
}

private AgentUriStatData getUriStatBatchBuilder(long currentBaseTimestamp) {
if (agentUriStatData == null) {
agentUriStatData = new AgentUriStatData(currentBaseTimestamp, collectInterval);
}
return agentUriStatData;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
public class DisabledUriStatStorage implements UriStatStorage {

@Override
public void store(UriStatInfo uriStatInfo) {
public void store(String uri, boolean status, long elapsedTime) {
// Do nothing
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@
*/
public interface UriStatStorage {

void store(UriStatInfo uriStatInfo);
void store(String uri, boolean status, long elapsedTime);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright 2020 NAVER Corp.
*
* 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 com.navercorp.pinpoint.profiler.monitor.metric.uri;

import com.navercorp.pinpoint.common.util.Assert;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
* @author Taejin Koo
*/
public class AgentUriStatData {

private final long baseTimestamp;
private final int interval;

private Map<String, EachUriStatData> eachUriStatDataMap = new HashMap<>();

public AgentUriStatData(long baseTimestamp, int interval) {
Assert.isTrue(baseTimestamp > 0, "baseTimestamp must be ` > 0`");
Assert.isTrue(interval > 0, "interval must be ` > 0`");

this.baseTimestamp = baseTimestamp;
this.interval = interval;
}

public long getBaseTimestamp() {
return baseTimestamp;
}

public int getInterval() {
return interval;
}

public void add(UriStatInfo uriStatInfo) {
String uri = uriStatInfo.getUri();

EachUriStatData eachUriStatData = eachUriStatDataMap.get(uri);
if (eachUriStatData == null) {
eachUriStatData = new EachUriStatData(uri);
eachUriStatDataMap.put(uri, eachUriStatData);
}

eachUriStatData.add(uriStatInfo);
}

public Collection<EachUriStatData> getAllUriStatData() {
return eachUriStatDataMap.values();
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder("UriStatData{");
sb.append("baseTimestamp=").append(baseTimestamp);
sb.append(", interval=").append(interval);
sb.append(", eachUriStatDataMap=").append(eachUriStatDataMap);
sb.append('}');
return sb.toString();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright 2020 NAVER Corp.
*
* 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 com.navercorp.pinpoint.profiler.monitor.metric.uri;

/**
* @author Taejin Koo
*/
public class EachUriStatData {

private final String uri;
private final UriStatHistogram totalHistogram = new UriStatHistogram();
private final UriStatHistogram failedHistogram = new UriStatHistogram();

public EachUriStatData(String uri) {
this.uri = uri;
}

public void add(UriStatInfo uriStatInfo) {
boolean status = uriStatInfo.isStatus();
totalHistogram.add(uriStatInfo.getElapsed());

if (!status) {
failedHistogram.add(uriStatInfo.getElapsed());
}
}

public String getUri() {
return uri;
}

public UriStatHistogram getTotalHistogram() {
return totalHistogram;
}

public UriStatHistogram getFailedHistogram() {
return failedHistogram;
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder("EachUriStatData{");
sb.append("uri='").append(uri).append('\'');
sb.append(", totalHistogram=").append(totalHistogram);
sb.append(", failedHistogram=").append(failedHistogram);
sb.append('}');
return sb.toString();
}
}
Loading

0 comments on commit af0a3f2

Please sign in to comment.