Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.opentsdb.tsd.KafkaHttpRpcPlugin Maven / Gradle / Ivy
// This file is part of OpenTSDB.
// Copyright (C) 2018 The OpenTSDB 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 net.opentsdb.tsd;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicLong;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.handler.codec.http.HttpMethod;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Maps;
import com.stumbleupon.async.Deferred;
import net.opentsdb.core.TSDB;
import net.opentsdb.stats.StatsCollector;
import net.opentsdb.tools.BuildData;
import net.opentsdb.utils.JSON;
public class KafkaHttpRpcPlugin extends HttpRpcPlugin {
private static final Logger LOG = LoggerFactory.getLogger(KafkaHttpRpcPlugin.class);
private TSDB tsdb;
@Override
public void initialize(TSDB tsdb) {
this.tsdb = tsdb;
LOG.info("Initialized KafkaHttpRpcPlugin");
}
@Override
public Deferred shutdown() {
return Deferred.fromResult(null);
}
@Override
public String version() {
return "2.4.0";
}
@Override
public void collectStats(StatsCollector collector) {
// TODO Auto-generated method stub
}
@Override
public String getPath() {
return "kafkarpc";
}
@Override
public void execute(final TSDB tsdb, final HttpRpcPluginQuery query) throws IOException {
// only accept GET/POST for now
if (query.request().getMethod() != HttpMethod.GET &&
query.request().getMethod() != HttpMethod.POST) {
throw new BadRequestException(HttpResponseStatus.METHOD_NOT_ALLOWED,
"Method not allowed", "The HTTP method [" + query.method().getName() +
"] is not permitted for this endpoint");
}
final String[] uri = query.explodePath();
final String endpoint = uri.length > 1 ? uri[2].toLowerCase() : "";
if ("version".equals(endpoint)) {
handleVersion(query);
} else if ("rate".equals(endpoint)) {
handleRate(query);
} else if ("namespace".equals(endpoint)) {
handlePerNamespaceStats(query);
} else if ("perthread".equals(endpoint)) {
handlePerThreadStats(query);
} else {
throw new BadRequestException(HttpResponseStatus.NOT_IMPLEMENTED,
"Hello. You have reached an API that has been disconnected. "
+ "Please call again.");
}
}
/**
* Prints Version information for the various components.
* @param query A non-null HTTP query to parse and respond to.
*/
private void handleVersion(final HttpRpcPluginQuery query) {
final Map> versions = Maps.newHashMap();
Map version = Maps.newHashMap();
version.put("version", BuildData.version);
version.put("short_revision", BuildData.short_revision);
version.put("full_revision", BuildData.full_revision);
version.put("timestamp", Long.toString(BuildData.timestamp));
version.put("repo_status", BuildData.repo_status.toString());
version.put("user", BuildData.user);
version.put("host", BuildData.host);
version.put("repo", BuildData.repo);
versions.put("tsdb", version);
// TODO - plugin version
query.sendBuffer(HttpResponseStatus.OK,
ChannelBuffers.wrappedBuffer(JSON.serializeToBytes(versions)),
"application/json");
}
/**
* Handles calls to print and/or adjust the rate per group
* @param query The HTTP query to parse and respond to.
*/
private void handleRate(final HttpRpcPluginQuery query) {
synchronized (tsdb) {
if (KafkaRpcPlugin.KAFKA_RPC_REFERENCE == null) {
throw new BadRequestException(HttpResponseStatus.CONFLICT,
"Consumers have not started yet");
}
// for now we'll just parse URI params to cheat
final String group_id = query.getQueryStringParam("group");
final double rate;
if (group_id != null && !group_id.isEmpty()) {
rate = Double.parseDouble(query.getRequiredQueryStringParam("rate"));
KafkaRpcPlugin.KAFKA_RPC_REFERENCE.setRate(group_id, rate);
} else {
rate = 0;
}
final Map rates =
KafkaRpcPlugin.KAFKA_RPC_REFERENCE.getRates();
query.sendBuffer(HttpResponseStatus.OK,
ChannelBuffers.wrappedBuffer(JSON.serializeToBytes(rates)),
"application/json");
}
}
/**
* Handles printing stats per namespace. Aggregated stats are included with
* the main tsdb /api/stats call. Users can filter by namespace if they want.
* @param query The HTTP query to parse and respond to.
*/
private void handlePerNamespaceStats(final HttpRpcPluginQuery query) {
synchronized (tsdb) {
if (KafkaRpcPlugin.KAFKA_RPC_REFERENCE == null) {
throw new BadRequestException(HttpResponseStatus.CONFLICT,
"Consumers have not started yet");
}
final String filter = query.getQueryStringParam("namespace");
final Map> counters =
KafkaRpcPlugin.KAFKA_RPC_REFERENCE.getNamespaceCounters();
final long ts = System.currentTimeMillis() / 1000;
// TSD format for ingest
final List> results = new ArrayList>();
for (final Entry> counter :
counters.entrySet()) {
for (final Entry metric : counter.getValue().entrySet()) {
if (filter != null && !filter.isEmpty() &&
!filter.toLowerCase().equals(metric.getKey().toLowerCase())) {
continue;
}
final Map entry = new HashMap(4);
entry.put("metric", "KafkaRpcPlugin.perNamespace." + counter.getKey());
entry.put("timestamp", ts);
entry.put("value", metric.getValue().get());
final Map tags = new HashMap(2);
tags.put("host", KafkaRpcPlugin.KAFKA_RPC_REFERENCE.getHost());
tags.put("namespace", metric.getKey());
entry.put("tags", tags);
results.add(entry);
}
}
query.sendBuffer(HttpResponseStatus.OK,
ChannelBuffers.wrappedBuffer(JSON.serializeToBytes(results)),
"application/json");
}
}
/** Publish per thread stats */
private void handlePerThreadStats(final HttpRpcPluginQuery query) {
synchronized (tsdb) {
if (KafkaRpcPlugin.KAFKA_RPC_REFERENCE == null) {
throw new BadRequestException(HttpResponseStatus.CONFLICT,
"Consumers have not started yet");
}
final long ts = System.currentTimeMillis() / 1000;
Map>> stats =
KafkaRpcPlugin.KAFKA_RPC_REFERENCE.getPerThreadStats();
// TSD format for ingest
final List> results = new ArrayList>();
for (final Entry>> group : stats.entrySet()) {
for (final Entry> thread : group.getValue().entrySet()) {
for (final Entry counter : thread.getValue().entrySet()) {
final Map entry = new HashMap(4);
entry.put("metric", "KafkaRpcPlugin.perThread." + counter.getKey());
entry.put("timestamp", ts);
entry.put("value", counter.getValue());
final Map tags = new HashMap(2);
tags.put("host", KafkaRpcPlugin.KAFKA_RPC_REFERENCE.getHost());
tags.put("consumer", group.getKey());
tags.put("thread", Integer.toString(thread.getKey()));
entry.put("tags", tags);
results.add(entry);
}
}
query.sendBuffer(HttpResponseStatus.OK,
ChannelBuffers.wrappedBuffer(JSON.serializeToBytes(results)),
"application/json");
}
}
}
}