github.com/instana/go-sensor@v1.62.2-0.20240520081010-4919868049e1/env_config.go (about) 1 // (c) Copyright IBM Corp. 2021 2 // (c) Copyright Instana Inc. 2020 3 4 package instana 5 6 import ( 7 "errors" 8 "fmt" 9 "strconv" 10 "strings" 11 "time" 12 ) 13 14 // parseInstanaTags parses the tags string passed via INSTANA_TAGS. 15 // The tag string is a comma-separated list of keys optionally followed by an '=' character and a string value: 16 // 17 // INSTANA_TAGS := key1[=value1][,key2[=value2],...] 18 // 19 // The leading and trailing space is truncated from key names, values are used as-is. If a key does not have 20 // value associated, it's considered to be nil. 21 func parseInstanaTags(s string) map[string]interface{} { 22 tags := make(map[string]interface{}) 23 24 for _, tag := range strings.Split(s, ",") { 25 kv := strings.SplitN(tag, "=", 2) 26 27 k := strings.TrimSpace(kv[0]) 28 if k == "" { 29 continue 30 } 31 32 var v interface{} 33 if len(kv) > 1 { 34 v = kv[1] 35 } 36 37 tags[k] = v 38 } 39 40 if len(tags) == 0 { 41 return nil 42 } 43 44 return tags 45 } 46 47 // parseInstanaSecrets parses the tags string passed via INSTANA_SECRETS. 48 // The secrets matcher configuration string is expected to have the following format: 49 // 50 // INSTANA_SECRETS := <matcher>:<secret>[,<secret>] 51 // 52 // Where `matcher` is one of: 53 // * `equals` - matches a string if it's contained in the secrets list 54 // * `equals-ignore-case` is a case-insensitive version of `equals` 55 // * `contains` matches a string if it contains any of the secrets list values 56 // * `contains-ignore-case` is a case-insensitive version of `contains` 57 // * `regex` matches a string if it fully matches any of the regular expressions provided in the secrets list 58 // 59 // This function returns an error if there is no matcher configuration provided. 60 func parseInstanaSecrets(s string) (Matcher, error) { 61 if s == "" { 62 return nil, errors.New("empty value for secret matcher configuration") 63 } 64 65 ind := strings.Index(s, ":") 66 if ind < 0 { 67 return nil, fmt.Errorf("malformed secret matcher configuration: %q", s) 68 } 69 70 matcher, config := strings.TrimSpace(s[:ind]), strings.Split(s[ind+1:], ",") 71 72 return NamedMatcher(matcher, config) 73 } 74 75 // parseInstanaExtraHTTPHeaders parses the tags string passed via INSTANA_EXTRA_HTTP_HEADERS. 76 // The header names are expected to come in a semicolon-separated list: 77 // 78 // INSTANA_EXTRA_HTTP_HEADERS := header1[;header2;...] 79 // 80 // Any leading and trailing whitespace characters will be trimmed from header names. 81 func parseInstanaExtraHTTPHeaders(s string) []string { 82 var headers []string 83 for _, h := range strings.Split(s, ";") { 84 h = strings.TrimSpace(h) 85 if h == "" { 86 continue 87 } 88 89 headers = append(headers, h) 90 } 91 92 return headers 93 } 94 95 // parseInstanaTimeout parses the Instana backend connection timeout passed via INSTANA_TIMEOUT. 96 // The value is expected to be an integer number of milliseconds, greate than 0. 97 // This function returns the default timeout 500ms if provided with an empty string. 98 func parseInstanaTimeout(s string) (time.Duration, error) { 99 if s == "" { 100 return defaultServerlessTimeout, nil 101 } 102 103 ms, err := strconv.ParseUint(s, 10, 64) 104 if err != nil || ms < 1 { 105 return 0, fmt.Errorf("invalid timeout value: %q", s) 106 } 107 108 return time.Duration(ms) * time.Millisecond, nil 109 }