001package io.prometheus.metrics.config; 002 003import javax.annotation.Nullable; 004 005public enum EscapingScheme { 006 /** NO_ESCAPING indicates that a name will not be escaped. */ 007 ALLOW_UTF8("allow-utf-8"), 008 009 /** UNDERSCORE_ESCAPING replaces all legacy-invalid characters with underscores. */ 010 UNDERSCORE_ESCAPING("underscores"), 011 012 /** 013 * DOTS_ESCAPING is similar to UNDERSCORE_ESCAPING, except that dots are converted to `_dot_` and 014 * pre-existing underscores are converted to `__`. 015 */ 016 DOTS_ESCAPING("dots"), 017 018 /** 019 * VALUE_ENCODING_ESCAPING prepends the name with `U__` and replaces all invalid characters with 020 * the Unicode value, surrounded by underscores. Single underscores are replaced with double 021 * underscores. 022 */ 023 VALUE_ENCODING_ESCAPING("values"); 024 025 private static final String ESCAPING_KEY = "escaping"; 026 027 /** Default escaping scheme for names when not specified. */ 028 public static final EscapingScheme DEFAULT = UNDERSCORE_ESCAPING; 029 030 public final String getValue() { 031 return value; 032 } 033 034 private final String value; 035 036 EscapingScheme(String value) { 037 this.value = value; 038 } 039 040 /** 041 * fromAcceptHeader returns an EscapingScheme depending on the Accept header. Iff the header 042 * contains an escaping=allow-utf-8 term, it will select NO_ESCAPING. If a valid "escaping" term 043 * exists, that will be used. Otherwise, the global default will be returned. 044 */ 045 public static EscapingScheme fromAcceptHeader(@Nullable String acceptHeader) { 046 if (acceptHeader != null) { 047 for (String p : acceptHeader.split(";")) { 048 String[] toks = p.split("="); 049 if (toks.length != 2) { 050 continue; 051 } 052 String key = toks[0].trim(); 053 String value = toks[1].trim(); 054 if (key.equals(ESCAPING_KEY)) { 055 try { 056 return EscapingScheme.forString(value); 057 } catch (IllegalArgumentException e) { 058 // If the escaping parameter is unknown, ignore it. 059 return DEFAULT; 060 } 061 } 062 } 063 } 064 return DEFAULT; 065 } 066 067 static EscapingScheme forString(String value) { 068 switch (value) { 069 case "allow-utf-8": 070 return ALLOW_UTF8; 071 case "underscores": 072 return UNDERSCORE_ESCAPING; 073 case "dots": 074 return DOTS_ESCAPING; 075 case "values": 076 return VALUE_ENCODING_ESCAPING; 077 default: 078 throw new IllegalArgumentException("Unknown escaping scheme: " + value); 079 } 080 } 081 082 public String toHeaderFormat() { 083 return "; " + ESCAPING_KEY + "=" + value; 084 } 085}