/* * Copyright 2013-2015 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.springframework.cloud.netflix.metrics; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.http.HttpRequest; import org.springframework.http.client.ClientHttpResponse; import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerMapping; /** * @author Jon Schneider */ public class DefaultMetricsTagProvider implements MetricsTagProvider { @Override public Map<String, String> clientHttpRequestTags(HttpRequest request, ClientHttpResponse response) { String urlTemplate = RestTemplateUrlTemplateHolder.getRestTemplateUrlTemplate(); if (urlTemplate == null) { urlTemplate = "none"; } String status; try { status = (response == null) ? "CLIENT_ERROR" : ((Integer) response .getRawStatusCode()).toString(); } catch (IOException e) { status = "IO_ERROR"; } String host = request.getURI().getHost(); if( host == null ) { host = "none"; } String strippedUrlTemplate = urlTemplate.replaceAll("^https?://[^/]+/", ""); Map<String, String> tags = new HashMap<>(); tags.put("method", request.getMethod().name()); tags.put("uri", sanitizeUrlTemplate(strippedUrlTemplate)); tags.put("status", status); tags.put("clientName", host); return Collections.unmodifiableMap(tags); } @Override public Map<String, String> httpRequestTags(HttpServletRequest request, HttpServletResponse response, Object handler, String caller) { Map<String, String> tags = new HashMap<>(); tags.put("method", request.getMethod()); tags.put("status", ((Integer) response.getStatus()).toString()); String uri = (String) request .getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); if (uri == null) { uri = request.getPathInfo(); } if (!StringUtils.hasText(uri)) { uri = "/"; } uri = sanitizeUrlTemplate(uri.substring(1)); tags.put("uri", uri.isEmpty() ? "root" : uri); Object exception = request.getAttribute("exception"); if (exception != null) { tags.put("exception", exception.getClass().getSimpleName()); } if (caller != null) { tags.put("caller", caller); } return tags; } /** * As is, the urlTemplate is not suitable for use with Atlas, as all interactions with * Atlas take place via query parameters */ protected String sanitizeUrlTemplate(String urlTemplate) { String sanitized = urlTemplate .replaceAll("\\{(\\w+):.+}(?=/|$)", "-$1-") // extract path variable names from regex expressions .replaceAll("/", "_") .replaceAll("[{}]", "-"); if (!StringUtils.hasText(sanitized)) { sanitized = "none"; } return sanitized; } }