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  }