[OSS] feat: add access log config to consul envoy connect (#15946)

This commit is contained in:
Dan Stough 2023-01-09 15:16:00 -05:00 committed by GitHub
parent a7b34d50fc
commit 88b9420a1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 618 additions and 8 deletions

View File

@ -27,9 +27,15 @@ type BootstrapTplArgs struct {
// TLS is enabled. // TLS is enabled.
AgentCAPEM string AgentCAPEM string
// AdminAccessLogConfig string representations of Envoy access log
// configurations for the admin interface.
AdminAccessLogConfig []string
// AdminAccessLogPath The path to write the access log for the // AdminAccessLogPath The path to write the access log for the
// administration server. If no access log is desired specify // administration server. If no access log is desired specify
// "/dev/null". By default it will use "/dev/null". // "/dev/null". By default it will use "/dev/null". Will be overriden by
// AdminAccessLogConfig.
// DEPRECATED: use AdminAccessLogConfig
AdminAccessLogPath string AdminAccessLogPath string
// AdminBindAddress is the address the Envoy admin server should bind to. // AdminBindAddress is the address the Envoy admin server should bind to.
@ -151,7 +157,16 @@ type GRPC struct {
// config. // config.
const bootstrapTemplate = `{ const bootstrapTemplate = `{
"admin": { "admin": {
{{- if (not .AdminAccessLogConfig) }}
"access_log_path": "{{ .AdminAccessLogPath }}", "access_log_path": "{{ .AdminAccessLogPath }}",
{{- end}}
{{- if .AdminAccessLogConfig }}
"access_log": [
{{- range $index, $element := .AdminAccessLogConfig}}
{{if $index}},{{end}}
{{$element}}
{{end}}],
{{- end}}
"address": { "address": {
"socket_address": { "socket_address": {
"address": "{{ .AdminBindAddress }}", "address": "{{ .AdminBindAddress }}",

View File

@ -11,18 +11,20 @@ import (
"strings" "strings"
"time" "time"
"github.com/golang/protobuf/jsonpb"
"github.com/hashicorp/go-version"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
"github.com/mitchellh/mapstructure" "github.com/mitchellh/mapstructure"
"github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/agent/xds" "github.com/hashicorp/consul/agent/xds"
"github.com/hashicorp/consul/agent/xds/accesslogs"
"github.com/hashicorp/consul/agent/xds/proxysupport" "github.com/hashicorp/consul/agent/xds/proxysupport"
"github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api"
proxyCmd "github.com/hashicorp/consul/command/connect/proxy" proxyCmd "github.com/hashicorp/consul/command/connect/proxy"
"github.com/hashicorp/consul/command/flags" "github.com/hashicorp/consul/command/flags"
"github.com/hashicorp/consul/ipaddr" "github.com/hashicorp/consul/ipaddr"
"github.com/hashicorp/consul/tlsutil" "github.com/hashicorp/consul/tlsutil"
"github.com/hashicorp/go-version"
) )
func New(ui cli.Ui) *cmd { func New(ui cli.Ui) *cmd {
@ -115,9 +117,7 @@ func (c *cmd) init() {
"$PATH. Ignored if -bootstrap is used.") "$PATH. Ignored if -bootstrap is used.")
c.flags.StringVar(&c.adminAccessLogPath, "admin-access-log-path", DefaultAdminAccessLogPath, c.flags.StringVar(&c.adminAccessLogPath, "admin-access-log-path", DefaultAdminAccessLogPath,
fmt.Sprintf("The path to write the access log for the administration server. If no access "+ "DEPRECATED: use proxy-defaults.accessLogs to set Envoy access logs.")
"log is desired specify %q. By default it will use %q.",
DefaultAdminAccessLogPath, DefaultAdminAccessLogPath))
c.flags.StringVar(&c.adminBind, "admin-bind", "localhost:19000", c.flags.StringVar(&c.adminBind, "admin-bind", "localhost:19000",
"The address:port to start envoy's admin server on. Envoy requires this "+ "The address:port to start envoy's admin server on. Envoy requires this "+
@ -442,6 +442,11 @@ func (c *cmd) run(args []string) int {
} }
} }
if c.adminAccessLogPath != DefaultAdminAccessLogPath {
c.UI.Warn("-admin-access-log-path is deprecated and will be removed in a future version of Consul. " +
"Configure access logging with proxy-defaults.accessLogs.")
}
// Generate config // Generate config
bootstrapJson, err := c.generateConfig() bootstrapJson, err := c.generateConfig()
if err != nil { if err != nil {
@ -673,6 +678,10 @@ func (c *cmd) generateConfig() ([]byte, error) {
args.Datacenter = datacenter args.Datacenter = datacenter
} }
if err := generateAccessLogs(c, args); err != nil {
return nil, err
}
// Setup ready listener for ingress gateway to pass healthcheck // Setup ready listener for ingress gateway to pass healthcheck
if c.gatewayKind == api.ServiceKindIngressGateway { if c.gatewayKind == api.ServiceKindIngressGateway {
lanAddr := c.lanAddress.String() lanAddr := c.lanAddress.String()
@ -694,6 +703,58 @@ func (c *cmd) generateConfig() ([]byte, error) {
return bsCfg.GenerateJSON(args, c.omitDeprecatedTags) return bsCfg.GenerateJSON(args, c.omitDeprecatedTags)
} }
// generateAccessLogs checks if there is any access log customization from proxy-defaults.
// If available, access log parameters are marshaled to JSON and added to the bootstrap template args.
func generateAccessLogs(c *cmd, args *BootstrapTplArgs) error {
configEntry, _, err := c.client.ConfigEntries().Get(api.ProxyDefaults, api.ProxyConfigGlobal, &api.QueryOptions{}) // Always assume the default partition
// We don't necessarily want to fail here if there isn't a proxy-defaults defined or if there
// is a server error.
var statusE api.StatusError
if err != nil && !errors.As(err, &statusE) {
return fmt.Errorf("failed fetch proxy-defaults: %w", err)
}
if configEntry != nil {
proxyDefaults, ok := configEntry.(*api.ProxyConfigEntry)
if !ok {
return fmt.Errorf("config entry %s is not a valid proxy-default", configEntry.GetName())
}
if proxyDefaults.AccessLogs != nil {
logConfig := &structs.AccessLogsConfig{
Enabled: proxyDefaults.AccessLogs.Enabled,
DisableListenerLogs: false,
Type: structs.LogSinkType(proxyDefaults.AccessLogs.Type),
JSONFormat: proxyDefaults.AccessLogs.JSONFormat,
TextFormat: proxyDefaults.AccessLogs.TextFormat,
Path: proxyDefaults.AccessLogs.Path,
}
envoyLogs, err := accesslogs.MakeAccessLogs(logConfig, false)
if err != nil {
return fmt.Errorf("failure generating Envoy access log configuration: %w", err)
}
// Convert individual proto messages to JSON here
args.AdminAccessLogConfig = make([]string, 0, len(envoyLogs))
marshaler := jsonpb.Marshaler{}
for _, msg := range envoyLogs {
config, err := marshaler.MarshalToString(msg)
if err != nil {
return fmt.Errorf("could not marshal Envoy access log configuration: %w", err)
}
args.AdminAccessLogConfig = append(args.AdminAccessLogConfig, config)
}
}
if proxyDefaults.AccessLogs != nil && c.adminAccessLogPath != DefaultAdminAccessLogPath {
c.UI.Warn("-admin-access-log-path and proxy-defaults.accessLogs both specify Envoy access log configuration. Ignoring the deprecated -admin-access-log-path flag.")
}
}
return nil
}
// TODO: make method a function // TODO: make method a function
func (c *cmd) xdsAddress() (GRPC, error) { func (c *cmd) xdsAddress() (GRPC, error) {
g := GRPC{} g := GRPC{}

View File

@ -13,14 +13,13 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/hashicorp/consul/agent/xds/proxysupport"
"github.com/stretchr/testify/assert"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/hashicorp/consul/agent" "github.com/hashicorp/consul/agent"
"github.com/hashicorp/consul/agent/xds" "github.com/hashicorp/consul/agent/xds"
"github.com/hashicorp/consul/agent/xds/proxysupport"
"github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/sdk/testutil"
) )
@ -118,6 +117,7 @@ type generateConfigTestCase struct {
Env []string Env []string
Files map[string]string Files map[string]string
ProxyConfig map[string]interface{} ProxyConfig map[string]interface{}
ProxyDefaults api.ProxyConfigEntry
NamespacesEnabled bool NamespacesEnabled bool
XDSPorts agent.GRPCPorts // used to mock an agent's configured gRPC ports. Plaintext defaults to 8502 and TLS defaults to 8503. XDSPorts agent.GRPCPorts // used to mock an agent's configured gRPC ports. Plaintext defaults to 8502 and TLS defaults to 8503.
AgentSelf110 bool // fake the agent API from versions v1.10 and earlier AgentSelf110 bool // fake the agent API from versions v1.10 and earlier
@ -1064,6 +1064,58 @@ func TestGenerateConfig(t *testing.T) {
PrometheusScrapePath: "/metrics", PrometheusScrapePath: "/metrics",
}, },
}, },
{
Name: "access-logs-enabled",
Flags: []string{"-proxy-id", "test-proxy"},
WantArgs: BootstrapTplArgs{
ProxyCluster: "test-proxy",
ProxyID: "test-proxy",
ProxySourceService: "",
GRPC: GRPC{
AgentAddress: "127.0.0.1",
AgentPort: "8502",
},
AdminAccessLogPath: "/dev/null",
AdminBindAddress: "127.0.0.1",
AdminBindPort: "19000",
LocalAgentClusterName: xds.LocalAgentClusterName,
PrometheusBackendPort: "",
PrometheusScrapePath: "/metrics",
},
ProxyDefaults: api.ProxyConfigEntry{
AccessLogs: &api.AccessLogsConfig{
Enabled: true,
},
},
},
{
Name: "access-logs-enabled-custom",
Flags: []string{"-proxy-id", "test-proxy"},
WantArgs: BootstrapTplArgs{
ProxyCluster: "test-proxy",
ProxyID: "test-proxy",
ProxySourceService: "",
GRPC: GRPC{
AgentAddress: "127.0.0.1",
AgentPort: "8502",
},
AdminAccessLogPath: "/dev/null",
AdminBindAddress: "127.0.0.1",
AdminBindPort: "19000",
LocalAgentClusterName: xds.LocalAgentClusterName,
PrometheusBackendPort: "",
PrometheusScrapePath: "/metrics",
},
ProxyDefaults: api.ProxyConfigEntry{
AccessLogs: &api.AccessLogsConfig{
Enabled: true,
DisableListenerLogs: true, // Should have no effect here
Type: api.FileLogSinkType,
Path: "/var/log/consul.log",
TextFormat: "MY START TIME %START_TIME%",
},
},
},
} }
cases = append(cases, enterpriseGenerateConfigTestCases()...) cases = append(cases, enterpriseGenerateConfigTestCases()...)
@ -1262,6 +1314,8 @@ func testMockAgent(tc generateConfigTestCase) http.HandlerFunc {
testMockAgentSelf(tc.XDSPorts, tc.AgentSelf110)(w, r) testMockAgentSelf(tc.XDSPorts, tc.AgentSelf110)(w, r)
case strings.Contains(r.URL.Path, "/catalog/node-services"): case strings.Contains(r.URL.Path, "/catalog/node-services"):
testMockCatalogNodeServiceList()(w, r) testMockCatalogNodeServiceList()(w, r)
case strings.Contains(r.URL.Path, "/config/proxy-defaults/global"):
testMockConfigProxyDefaults(tc.ProxyDefaults)(w, r)
default: default:
http.NotFound(w, r) http.NotFound(w, r)
} }
@ -1401,6 +1455,18 @@ func testMockCatalogNodeServiceList() http.HandlerFunc {
} }
} }
func testMockConfigProxyDefaults(entry api.ProxyConfigEntry) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cfgJSON, err := json.Marshal(entry)
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
w.Write(cfgJSON)
}
}
func TestEnvoyCommand_canBindInternal(t *testing.T) { func TestEnvoyCommand_canBindInternal(t *testing.T) {
t.Parallel() t.Parallel()
type testCheck struct { type testCheck struct {

View File

@ -0,0 +1,223 @@
{
"admin": {
"access_log": [
{
"name": "Consul Listener Filter Log",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog",
"path": "/var/log/consul.log",
"logFormat": {
"textFormatSource": {
"inlineString": "MY START TIME %START_TIME%\n"
}
}
}
}
],
"address": {
"socket_address": {
"address": "127.0.0.1",
"port_value": 19000
}
}
},
"node": {
"cluster": "test",
"id": "test-proxy",
"metadata": {
"namespace": "default",
"partition": "default"
}
},
"layered_runtime": {
"layers": [
{
"name": "base",
"static_layer": {
"re2.max_program_size.error_level": 1048576
}
}
]
},
"static_resources": {
"clusters": [
{
"name": "local_agent",
"ignore_health_on_host_removal": false,
"connect_timeout": "1s",
"type": "STATIC",
"http2_protocol_options": {},
"loadAssignment": {
"clusterName": "local_agent",
"endpoints": [
{
"lbEndpoints": [
{
"endpoint": {
"address": {
"socket_address": {
"address": "127.0.0.1",
"port_value": 8502
}
}
}
}
]
}
]
}
}
]
},
"stats_config": {
"stats_tags": [
{
"regex": "^cluster\\.(?:passthrough~)?((?:([^.]+)~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.custom_hash"
},
{
"regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:([^.]+)\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.service_subset"
},
{
"regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?([^.]+)\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.service"
},
{
"regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.namespace"
},
{
"regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:([^.]+)\\.)?[^.]+\\.internal[^.]*\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.partition"
},
{
"regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?([^.]+)\\.internal[^.]*\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.datacenter"
},
{
"regex": "^cluster\\.([^.]+\\.(?:[^.]+\\.)?([^.]+)\\.external\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.peer"
},
{
"regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.routing_type"
},
{
"regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.([^.]+)\\.consul\\.)",
"tag_name": "consul.destination.trust_domain"
},
{
"regex": "^cluster\\.(?:passthrough~)?(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+)\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.target"
},
{
"regex": "^cluster\\.(?:passthrough~)?(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+)\\.consul\\.)",
"tag_name": "consul.destination.full_target"
},
{
"regex": "^(?:tcp|http)\\.upstream(?:_peered)?\\.(([^.]+)(?:\\.[^.]+)?(?:\\.[^.]+)?\\.[^.]+\\.)",
"tag_name": "consul.upstream.service"
},
{
"regex": "^(?:tcp|http)\\.upstream\\.([^.]+(?:\\.[^.]+)?(?:\\.[^.]+)?\\.([^.]+)\\.)",
"tag_name": "consul.upstream.datacenter"
},
{
"regex": "^(?:tcp|http)\\.upstream_peered\\.([^.]+(?:\\.[^.]+)?\\.([^.]+)\\.)",
"tag_name": "consul.upstream.peer"
},
{
"regex": "^(?:tcp|http)\\.upstream(?:_peered)?\\.([^.]+(?:\\.([^.]+))?(?:\\.[^.]+)?\\.[^.]+\\.)",
"tag_name": "consul.upstream.namespace"
},
{
"regex": "^(?:tcp|http)\\.upstream\\.([^.]+(?:\\.[^.]+)?(?:\\.([^.]+))?\\.[^.]+\\.)",
"tag_name": "consul.upstream.partition"
},
{
"regex": "^cluster\\.((?:([^.]+)~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.custom_hash"
},
{
"regex": "^cluster\\.((?:[^.]+~)?(?:([^.]+)\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.service_subset"
},
{
"regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?([^.]+)\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.service"
},
{
"regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.namespace"
},
{
"regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?([^.]+)\\.internal[^.]*\\.[^.]+\\.consul\\.)",
"tag_name": "consul.datacenter"
},
{
"regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.[^.]+\\.consul\\.)",
"tag_name": "consul.routing_type"
},
{
"regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.([^.]+)\\.consul\\.)",
"tag_name": "consul.trust_domain"
},
{
"regex": "^cluster\\.(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+)\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.target"
},
{
"regex": "^cluster\\.(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+)\\.consul\\.)",
"tag_name": "consul.full_target"
},
{
"tag_name": "local_cluster",
"fixed_value": "test"
},
{
"tag_name": "consul.source.service",
"fixed_value": "test"
},
{
"tag_name": "consul.source.namespace",
"fixed_value": "default"
},
{
"tag_name": "consul.source.partition",
"fixed_value": "default"
},
{
"tag_name": "consul.source.datacenter",
"fixed_value": "dc1"
}
],
"use_all_default_tags": true
},
"dynamic_resources": {
"lds_config": {
"ads": {},
"resource_api_version": "V3"
},
"cds_config": {
"ads": {},
"resource_api_version": "V3"
},
"ads_config": {
"api_type": "DELTA_GRPC",
"transport_api_version": "V3",
"grpc_services": {
"initial_metadata": [
{
"key": "x-consul-token",
"value": ""
}
],
"envoy_grpc": {
"cluster_name": "local_agent"
}
}
}
}
}

View File

@ -0,0 +1,245 @@
{
"admin": {
"access_log": [
{
"name": "Consul Listener Filter Log",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog",
"logFormat": {
"jsonFormat": {
"authority": "%REQ(:AUTHORITY)%",
"bytes_received": "%BYTES_RECEIVED%",
"bytes_sent": "%BYTES_SENT%",
"connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%",
"downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%",
"downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%",
"duration": "%DURATION%",
"method": "%REQ(:METHOD)%",
"path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%",
"protocol": "%PROTOCOL%",
"request_id": "%REQ(X-REQUEST-ID)%",
"requested_server_name": "%REQUESTED_SERVER_NAME%",
"response_code": "%RESPONSE_CODE%",
"response_code_details": "%RESPONSE_CODE_DETAILS%",
"response_flags": "%RESPONSE_FLAGS%",
"route_name": "%ROUTE_NAME%",
"start_time": "%START_TIME%",
"upstream_cluster": "%UPSTREAM_CLUSTER%",
"upstream_host": "%UPSTREAM_HOST%",
"upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%",
"upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%",
"upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%",
"user_agent": "%REQ(USER-AGENT)%",
"x_forwarded_for": "%REQ(X-FORWARDED-FOR)%"
}
}
}
}
],
"address": {
"socket_address": {
"address": "127.0.0.1",
"port_value": 19000
}
}
},
"node": {
"cluster": "test",
"id": "test-proxy",
"metadata": {
"namespace": "default",
"partition": "default"
}
},
"layered_runtime": {
"layers": [
{
"name": "base",
"static_layer": {
"re2.max_program_size.error_level": 1048576
}
}
]
},
"static_resources": {
"clusters": [
{
"name": "local_agent",
"ignore_health_on_host_removal": false,
"connect_timeout": "1s",
"type": "STATIC",
"http2_protocol_options": {},
"loadAssignment": {
"clusterName": "local_agent",
"endpoints": [
{
"lbEndpoints": [
{
"endpoint": {
"address": {
"socket_address": {
"address": "127.0.0.1",
"port_value": 8502
}
}
}
}
]
}
]
}
}
]
},
"stats_config": {
"stats_tags": [
{
"regex": "^cluster\\.(?:passthrough~)?((?:([^.]+)~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.custom_hash"
},
{
"regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:([^.]+)\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.service_subset"
},
{
"regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?([^.]+)\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.service"
},
{
"regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.namespace"
},
{
"regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:([^.]+)\\.)?[^.]+\\.internal[^.]*\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.partition"
},
{
"regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?([^.]+)\\.internal[^.]*\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.datacenter"
},
{
"regex": "^cluster\\.([^.]+\\.(?:[^.]+\\.)?([^.]+)\\.external\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.peer"
},
{
"regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.routing_type"
},
{
"regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.([^.]+)\\.consul\\.)",
"tag_name": "consul.destination.trust_domain"
},
{
"regex": "^cluster\\.(?:passthrough~)?(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+)\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.destination.target"
},
{
"regex": "^cluster\\.(?:passthrough~)?(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+)\\.consul\\.)",
"tag_name": "consul.destination.full_target"
},
{
"regex": "^(?:tcp|http)\\.upstream(?:_peered)?\\.(([^.]+)(?:\\.[^.]+)?(?:\\.[^.]+)?\\.[^.]+\\.)",
"tag_name": "consul.upstream.service"
},
{
"regex": "^(?:tcp|http)\\.upstream\\.([^.]+(?:\\.[^.]+)?(?:\\.[^.]+)?\\.([^.]+)\\.)",
"tag_name": "consul.upstream.datacenter"
},
{
"regex": "^(?:tcp|http)\\.upstream_peered\\.([^.]+(?:\\.[^.]+)?\\.([^.]+)\\.)",
"tag_name": "consul.upstream.peer"
},
{
"regex": "^(?:tcp|http)\\.upstream(?:_peered)?\\.([^.]+(?:\\.([^.]+))?(?:\\.[^.]+)?\\.[^.]+\\.)",
"tag_name": "consul.upstream.namespace"
},
{
"regex": "^(?:tcp|http)\\.upstream\\.([^.]+(?:\\.[^.]+)?(?:\\.([^.]+))?\\.[^.]+\\.)",
"tag_name": "consul.upstream.partition"
},
{
"regex": "^cluster\\.((?:([^.]+)~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.custom_hash"
},
{
"regex": "^cluster\\.((?:[^.]+~)?(?:([^.]+)\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.service_subset"
},
{
"regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?([^.]+)\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.service"
},
{
"regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.namespace"
},
{
"regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?([^.]+)\\.internal[^.]*\\.[^.]+\\.consul\\.)",
"tag_name": "consul.datacenter"
},
{
"regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.[^.]+\\.consul\\.)",
"tag_name": "consul.routing_type"
},
{
"regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.([^.]+)\\.consul\\.)",
"tag_name": "consul.trust_domain"
},
{
"regex": "^cluster\\.(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+)\\.[^.]+\\.[^.]+\\.consul\\.)",
"tag_name": "consul.target"
},
{
"regex": "^cluster\\.(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+)\\.consul\\.)",
"tag_name": "consul.full_target"
},
{
"tag_name": "local_cluster",
"fixed_value": "test"
},
{
"tag_name": "consul.source.service",
"fixed_value": "test"
},
{
"tag_name": "consul.source.namespace",
"fixed_value": "default"
},
{
"tag_name": "consul.source.partition",
"fixed_value": "default"
},
{
"tag_name": "consul.source.datacenter",
"fixed_value": "dc1"
}
],
"use_all_default_tags": true
},
"dynamic_resources": {
"lds_config": {
"ads": {},
"resource_api_version": "V3"
},
"cds_config": {
"ads": {},
"resource_api_version": "V3"
},
"ads_config": {
"api_type": "DELTA_GRPC",
"transport_api_version": "V3",
"grpc_services": {
"initial_metadata": [
{
"key": "x-consul-token",
"value": ""
}
],
"envoy_grpc": {
"cluster_name": "local_agent"
}
}
}
}
}