From 0ca3aef0f56f38c62a86ea880c82af79e0c5731d Mon Sep 17 00:00:00 2001 From: Giancarlo Rubio Date: Mon, 27 Feb 2017 11:00:31 +0100 Subject: [PATCH] Add ability to customize upstream and stream log format --- controllers/nginx/pkg/config/config.go | 24 +++++++++++++++++ controllers/nginx/pkg/config/config_test.go | 27 +++++++++++++++++++ controllers/nginx/pkg/template/template.go | 24 ++++++++++++----- .../rootfs/etc/nginx/template/nginx.tmpl | 8 +++--- 4 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 controllers/nginx/pkg/config/config_test.go diff --git a/controllers/nginx/pkg/config/config.go b/controllers/nginx/pkg/config/config.go index bfe4cc79e..c23c15867 100644 --- a/controllers/nginx/pkg/config/config.go +++ b/controllers/nginx/pkg/config/config.go @@ -21,6 +21,7 @@ import ( "github.com/golang/glog" + "fmt" "k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/ingress/defaults" ) @@ -46,6 +47,10 @@ const ( gzipTypes = "application/atom+xml application/javascript application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/plain text/x-component" + logFormatUpstream = "'%v - [$proxy_add_x_forwarded_for] - $remote_user [$time_local] \"$request\" $status $body_bytes_sent \"$http_referer\" \"$http_user_agent\" $request_length $request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status'" + + logFormatStream = "'$remote_addr [$time_local] $protocol [$ssl_preread_server_name] [$stream_upstream] $status $bytes_sent $bytes_received $session_time'" + // http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_buffer_size // Sets the size of the buffer used for sending data. // 4k helps NGINX to improve TLS Time To First Byte (TTTFB) @@ -143,6 +148,14 @@ type Configuration struct { // Default: 4 8k LargeClientHeaderBuffers string `json:"large-client-header-buffers"` + // Customize upstream log_format + // http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format + LogFormatUpstream string `json:"log-format-upstream,omitempty"` + + // Customize stream log_format + // http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format + LogFormatStream string `json:"log-format-stream,omitempty"` + // Maximum number of simultaneous connections that can be opened by each worker process // http://nginx.org/en/docs/ngx_core_module.html#worker_connections MaxWorkerConnections int `json:"max-worker-connections,omitempty"` @@ -250,6 +263,8 @@ func NewDefault() Configuration { GzipTypes: gzipTypes, KeepAlive: 75, LargeClientHeaderBuffers: "4 8k", + LogFormatStream: logFormatStream, + LogFormatUpstream: BuildLogFormatUpstream(false), MaxWorkerConnections: 16384, MapHashBucketSize: 64, ProxyRealIPCIDR: defIPCIDR, @@ -291,6 +306,15 @@ func NewDefault() Configuration { return cfg } +// BuildLogFormatUpstream format the log_format upstream based on proxy_protocol +func BuildLogFormatUpstream(useProxyProtocol bool) string { + + if useProxyProtocol { + return fmt.Sprintf(logFormatUpstream, "$proxy_protocol_addr") + } + return fmt.Sprintf(logFormatUpstream, "$remote_addr") +} + // TemplateConfig contains the nginx configuration to render the file nginx.conf type TemplateConfig struct { ProxySetHeaders map[string]string diff --git a/controllers/nginx/pkg/config/config_test.go b/controllers/nginx/pkg/config/config_test.go new file mode 100644 index 000000000..d0fccc69b --- /dev/null +++ b/controllers/nginx/pkg/config/config_test.go @@ -0,0 +1,27 @@ +package config + +import ( + "fmt" + "testing" +) + +func TestBuildLogFormatUpstream(t *testing.T) { + + testCases := []struct { + useProxyProtocol bool // use proxy protocol + expected string + }{ + {true, fmt.Sprintf(logFormatUpstream, "$proxy_protocol_addr")}, + {false, fmt.Sprintf(logFormatUpstream, "$remote_addr")}, + } + + for _, testCase := range testCases { + + result := BuildLogFormatUpstream(testCase.useProxyProtocol) + + if result != testCase.expected { + t.Errorf(" expected %v but return %v", testCase.expected, result) + } + + } +} diff --git a/controllers/nginx/pkg/template/template.go b/controllers/nginx/pkg/template/template.go index 1945bc6cf..d23a78be2 100644 --- a/controllers/nginx/pkg/template/template.go +++ b/controllers/nginx/pkg/template/template.go @@ -31,6 +31,7 @@ import ( "github.com/golang/glog" "k8s.io/ingress/controllers/nginx/pkg/config" + nginxconfig "k8s.io/ingress/controllers/nginx/pkg/config" "k8s.io/ingress/core/pkg/ingress" ing_net "k8s.io/ingress/core/pkg/net" "k8s.io/ingress/core/pkg/watch" @@ -134,12 +135,12 @@ var ( "buildSSLPassthroughUpstreams": buildSSLPassthroughUpstreams, "buildResolvers": buildResolvers, "isLocationAllowed": isLocationAllowed, - - "contains": strings.Contains, - "hasPrefix": strings.HasPrefix, - "hasSuffix": strings.HasSuffix, - "toUpper": strings.ToUpper, - "toLower": strings.ToLower, + "buildLogFormatUpstream": buildLogFormatUpstream, + "contains": strings.Contains, + "hasPrefix": strings.HasPrefix, + "hasSuffix": strings.HasSuffix, + "toUpper": strings.ToUpper, + "toLower": strings.ToLower, } ) @@ -227,6 +228,17 @@ func buildAuthLocation(input interface{}) string { return fmt.Sprintf("/_external-auth-%v", str) } +func buildLogFormatUpstream(input interface{}) string { + config, ok := input.(config.Configuration) + + if !ok { + glog.Errorf("error an ingress.buildLogFormatUpstream type but %T was returned", input) + } + + return nginxconfig.BuildLogFormatUpstream(config.UseProxyProtocol) + +} + // buildProxyPass produces the proxy pass string, if the ingress has redirects // (specified through the ingress.kubernetes.io/rewrite-to annotation) // If the annotation ingress.kubernetes.io/add-base-url:"true" is specified it will diff --git a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl index 4684a497c..ae06cd235 100644 --- a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl +++ b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl @@ -77,11 +77,9 @@ http { gzip_proxied any; {{ end }} - server_tokens {{ if $cfg.ShowServerTokens }}on{{ else }}off{{ end }}; + server_tokens {{ if $cfg.ShowServerTokens }}on{{ else }}off{{ end }}; - log_format upstreaminfo '{{ if $cfg.UseProxyProtocol }}$proxy_protocol_addr{{ else }}$remote_addr{{ end }} - ' - '[$proxy_add_x_forwarded_for] - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" ' - '$request_length $request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status'; + log_format upstreaminfo {{ buildLogFormatUpstream $cfg }}; {{/* map urls that should not appear in access.log */}} {{/* http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log */}} @@ -448,7 +446,7 @@ stream { default nginx-ssl-backend; } - log_format log_stream '$remote_addr [$time_local] $protocol [$ssl_preread_server_name] [$stream_upstream] $status $bytes_sent $bytes_received $session_time'; + log_format log_stream {{ $cfg.LogFormatStream }}; {{ if $cfg.DisableAccessLog }} access_log off;