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

org.apache.druid.emitter.opentsdb.EventConverter Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.druid.emitter.opentsdb;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Strings;
import org.apache.druid.java.util.common.ISE;
import org.apache.druid.java.util.common.StringUtils;
import org.apache.druid.java.util.common.logger.Logger;
import org.apache.druid.java.util.emitter.service.ServiceMetricEvent;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

public class EventConverter
{
  private static final Logger log = new Logger(EventConverter.class);
  private static final Pattern WHITESPACE = Pattern.compile("[\\s]+");

  private final Map> metricMap;
  private final String namespacePrefix;

  public EventConverter(ObjectMapper mapper, String metricMapPath, String namespacePrefix)
  {
    metricMap = readMap(mapper, metricMapPath);
    this.namespacePrefix = namespacePrefix;
  }

  protected String sanitize(String metric)
  {
    return WHITESPACE.matcher(metric.trim()).replaceAll("_").replace('/', '.');
  }

  private String buildMetric(String metric)
  {
    final String sanitized = sanitize(metric);
    if (namespacePrefix == null) {
      return sanitized;
    } else {
      return StringUtils.format("%s.%s", sanitize(namespacePrefix), sanitized);
    }
  }

  /**
   * This function will convert a druid event to a opentsdb event.
   * Also this function acts as a filter. It returns null if the event is not suppose to be emitted to Opentsdb.
   * And it will filter out dimensions which is not suppose to be emitted.
   *
   * @param serviceMetricEvent Druid event ot type {@link ServiceMetricEvent}
   *
   * @return {@link OpentsdbEvent} or null
   */
  public OpentsdbEvent convert(ServiceMetricEvent serviceMetricEvent)
  {
    String metric = serviceMetricEvent.getMetric();
    if (!metricMap.containsKey(metric)) {
      return null;
    }

    long timestamp = serviceMetricEvent.getCreatedTime().getMillis() / 1000L;
    Number value = serviceMetricEvent.getValue();

    Map tags = new HashMap<>();
    String service = serviceMetricEvent.getService().replace(':', '_');
    String host = serviceMetricEvent.getHost().replace(':', '_');
    tags.put("service", service);
    tags.put("host", host);

    Map userDims = serviceMetricEvent.getUserDims();
    for (String dim : metricMap.get(metric)) {
      if (userDims.containsKey(dim)) {
        Object dimValue = userDims.get(dim);
        if (dimValue instanceof String) {
          dimValue = ((String) dimValue).replace(':', '_');
        }
        tags.put(dim, dimValue);
      }
    }

    return new OpentsdbEvent(buildMetric(metric), timestamp, value, tags);
  }

  private Map> readMap(ObjectMapper mapper, String metricMapPath)
  {
    try {
      InputStream is;
      if (Strings.isNullOrEmpty(metricMapPath)) {
        log.info("Using default metric map");
        is = this.getClass().getClassLoader().getResourceAsStream("defaultMetrics.json");
      } else {
        log.info("Using default metric map located at [%s]", metricMapPath);
        is = new FileInputStream(new File(metricMapPath));
      }
      return mapper.readerFor(new TypeReference>>()
      {
      }).readValue(is);
    }
    catch (IOException e) {
      throw new ISE(e, "Failed to parse metrics and dimensions");
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy