@Override public String toString() { if (tags.isEmpty()) { return name; } final StringBuilder buf = new StringBuilder(); buf.append(name).append('{'); tags.forEach(tag -> buf.append(tag.getKey()).append('=') .append(tag.getValue()).append(',')); buf.setCharAt(buf.length() - 1, '}'); return buf.toString(); } }
private static String measurementName(Meter.Id id, Measurement measurement) { final StringBuilder buf = new StringBuilder(); // Append name. buf.append(id.getName()); // Append statistic. buf.append('#'); buf.append(measurement.getStatistic().getTagValueRepresentation()); // Append tags if there are any. final Iterator<Tag> tagsIterator = id.getTags().iterator(); if (tagsIterator.hasNext()) { buf.append('{'); tagsIterator.forEachRemaining(tag -> buf.append(tag.getKey()).append('=') .append(tag.getValue()).append(',')); buf.setCharAt(buf.length() - 1, '}'); } return buf.toString(); }
private void mergeAvailableTags(Map<String, Set<String>> availableTags, Meter meter) { meter.getId().getTags().forEach((tag) -> { Set<String> value = Collections.singleton(tag.getValue()); availableTags.merge(tag.getKey(), value, this::merge); }); }
@ReadOperation public MetricResponse metric(@Selector String requiredMetricName, @Nullable List<String> tag) { List<Tag> tags = parseTags(tag); Collection<Meter> meters = findFirstMatchingMeters(this.registry, requiredMetricName, tags); if (meters.isEmpty()) { return null; } Map<Statistic, Double> samples = getSamples(meters); Map<String, Set<String>> availableTags = getAvailableTags(meters); tags.forEach((t) -> availableTags.remove(t.getKey())); Meter.Id meterId = meters.iterator().next().getId(); return new MetricResponse(requiredMetricName, meterId.getDescription(), meterId.getBaseUnit(), asList(samples, Sample::new), asList(availableTags, AvailableTag::new)); }
/** * Logs a sorted and readable list of meters using the debug level. Useful for debugging. * * @param meters The meters to be logged. */ public static void logMeters(final Collection<? extends Meter> meters) { if (!log.isDebugEnabled()) { return; } // The original collection is usually unmodifiable final List<Meter> sortedMeters = new ArrayList<>(meters); Collections.sort(sortedMeters, METER_COMPARATOR); log.debug("Found meters:"); for (final Meter meter : sortedMeters) { final Id id = meter.getId(); final String type = id.getType().name(); final String name = id.getName(); final Map<String, String> tagMap = new LinkedHashMap<>(); // Tags are already sorted for (final Tag tag : id.getTags()) { tagMap.put(tag.getKey(), tag.getValue()); } log.debug("- {} {} {}", type, name, tagMap); } }
@Override public void serialize(Tag tag, JsonGenerator json, SerializerProvider provider) throws IOException { json.writeStartObject(); json.writeStringField(tag.getKey(), tag.getValue()); json.writeEndObject(); } }
private Optional<Tag> findTagByKey(Meter.Id id, String key) { return id.getTags().stream().filter(tag -> tag.getKey().equals(key)).findFirst(); } }
private List<Dimension> toDimensions(List<Tag> tags) { return tags.stream() .map(tag -> new Dimension().withName(tag.getKey()).withValue(tag.getValue())) .collect(toList()); } }
@Override public List<Context> getContext() { return counter.getId().getTags() .stream() .map(t -> new ContextImpl(t.getKey(), t.getValue())) .collect(Collectors.toList()); }
private Id spectatorId(Meter.Id id) { List<com.netflix.spectator.api.Tag> tags = getConventionTags(id).stream() .map(t -> new BasicTag(t.getKey(), t.getValue())) .collect(toList()); return registry.createId(getConventionName(id), tags); }
private Id convert(io.micrometer.core.instrument.Meter.Id id) { List<Tag> tags = id.getTags() .stream() .map(t -> Tag.of(t.getKey(), t.getValue())) .collect(Collectors.toList()); return Id.create(id.getName()).withTags(tags); }
String writeMetric(Meter.Id id, @Nullable String suffix, long wallTime, double value) { Meter.Id fullId = id; if (suffix != null) fullId = idWithSuffix(id, suffix); Iterable<Tag> tags = getConventionTags(fullId); String host = config.hostTag() == null ? "" : stream(tags.spliterator(), false) .filter(t -> requireNonNull(config.hostTag()).equals(t.getKey())) .findAny() .map(t -> ",\"host\":\"" + escapeJson(t.getValue()) + "\"") .orElse(""); String tagsArray = tags.iterator().hasNext() ? stream(tags.spliterator(), false) .map(t -> "\"" + escapeJson(t.getKey()) + ":" + escapeJson(t.getValue()) + "\"") .collect(joining(",", ",\"tags\":[", "]")) : ""; return "{\"metric\":\"" + escapeJson(getConventionName(fullId)) + "\"," + "\"points\":[[" + (wallTime / 1000) + ", " + value + "]]" + host + tagsArray + "}"; }
private String event(Meter.Id id, Iterable<Tag> extraTags, Attribute... attributes) { StringBuilder tagsJson = new StringBuilder(); for (Tag tag : getConventionTags(id)) { tagsJson.append(",\"").append(escapeJson(tag.getKey())).append("\":\"").append(escapeJson(tag.getValue())).append("\""); } NamingConvention convention = config().namingConvention(); for (Tag tag : extraTags) { tagsJson.append(",\"").append(escapeJson(convention.tagKey(tag.getKey()))) .append("\":\"").append(escapeJson(convention.tagValue(tag.getValue()))).append("\""); } return Arrays.stream(attributes) .map(attr -> ",\"" + attr.getName() + "\":" + DoubleFormat.decimalOrWhole(attr.getValue().doubleValue())) .collect(Collectors.joining("", "{\"eventType\":\"" + escapeJson(getConventionName(id)) + "\"", tagsJson + "}")); }
String writeDocument(Meter meter, Consumer<StringBuilder> consumer) { StringBuilder sb = new StringBuilder(INDEX_LINE); String timestamp = FORMATTER.format(Instant.ofEpochMilli(config().clock().wallTime())); String name = getConventionName(meter.getId()); String type = meter.getId().getType().toString().toLowerCase(); sb.append("{\"").append(config.timestampFieldName()).append("\":\"").append(timestamp).append('"') .append(",\"name\":\"").append(escapeJson(name)).append('"') .append(",\"type\":\"").append(type).append('"'); List<Tag> tags = getConventionTags(meter.getId()); for (Tag tag : tags) { sb.append(",\"").append(escapeJson(tag.getKey())).append("\":\"") .append(escapeJson(tag.getValue())).append('"'); } consumer.accept(sb); sb.append("}"); return sb.toString(); }
KairosMetricBuilder tags(List<Tag> tags) { KairosMetricBuilder tagBuilder = new KairosMetricBuilder(); if (tags.isEmpty()) { // tags field is required for KairosDB, use hostname as a default tag try { tagBuilder.field("hostname", InetAddress.getLocalHost().getHostName()); } catch (UnknownHostException ignore) { /* ignore */ } } else { for (Tag tag : tags) { tagBuilder.field(tag.getKey(), tag.getValue()); } } sb.append(",\"tags\":").append(tagBuilder.build()); return this; }
private String writeMetricProxy(Meter.Id id, @Nullable String suffix, long wallTime, double value) { Meter.Id fullId = id; if (suffix != null) fullId = idWithSuffix(id, suffix); // surrounding the name with double quotes allows for / and , in names return "\"" + getConventionName(fullId) + "\" " + DoubleFormat.decimalOrNan(value) + " " + (wallTime / 1000) + " source=" + config.source() + " " + getConventionTags(fullId) .stream() .map(t -> t.getKey() + "=\"" + t.getValue() + "\"") .collect(joining(" ")); }
private void updateIfNamingConventionChanged() { NamingConvention next = config.namingConvention(); if (this.namingConvention != next) { this.namingConvention = next; this.name = sanitize(next.name(id.getName(), id.getType(), id.getBaseUnit())); this.tags = HashTreePMap.empty(); this.conventionTags = id.getTagsAsIterable().iterator().hasNext() ? id.getConventionTags(this.namingConvention).stream() .map(t -> sanitize(t.getKey()) + "=" + sanitize(t.getValue())) .collect(Collectors.joining(",")) : null; this.tagsNoStat = tags(null, conventionTags, "=", "#"); } }
private void updateIfNamingConventionChanged() { NamingConvention next = config.namingConvention(); if (this.namingConvention != next) { this.namingConvention = next; this.name = next.name(sanitize(id.getName()), id.getType(), id.getBaseUnit()) + ":"; this.tags = HashTreePMap.empty(); this.conventionTags = id.getTagsAsIterable().iterator().hasNext() ? id.getConventionTags(this.namingConvention).stream() .map(t -> sanitize(t.getKey()) + ":" + sanitize(t.getValue())) .collect(Collectors.joining(",")) : null; this.tagsNoStat = tags(null, conventionTags, ":", "|#"); } }
private void updateIfNamingConventionChanged() { NamingConvention next = config.namingConvention(); if (this.namingConvention != next) { for (; ; ) { if (namingConventionUpdater.compareAndSet(this, this.namingConvention, next)) break; } this.name = telegrafEscape(next.name(id.getName(), id.getType(), id.getBaseUnit())); this.tags = HashTreePMap.empty(); this.conventionTags = id.getTagsAsIterable().iterator().hasNext() ? id.getConventionTags(this.namingConvention).stream() .map(t -> telegrafEscape(t.getKey()) + "=" + telegrafEscape(t.getValue())) .collect(Collectors.joining(",")) : null; this.tagsNoStat = tags(null, conventionTags, "=", ","); } }
private static String id(Meter m) { return m.getId().getName() + "[" + StreamSupport.stream(m.getId().getTags().spliterator(), false) .map(t -> t.getKey() + '=' + t.getValue()) .collect(Collectors.joining(",")) + "]"; }