@@ -19,9 +19,60 @@ import (
1919 "github.com/crunchydata/postgres-operator/pkg/apis/postgres-operator.crunchydata.com/v1beta1"
2020)
2121
22+ func PostgreSQLParameters (ctx context.Context ,
23+ inCluster * v1beta1.PostgresCluster ,
24+ outParameters * postgres.Parameters ,
25+ ) {
26+ version := inCluster .Spec .PostgresVersion
27+
28+ if OpenTelemetryLogsEnabled (ctx , inCluster ) {
29+ var spec * v1beta1.InstrumentationLogsSpec
30+ if inCluster != nil && inCluster .Spec .Instrumentation != nil {
31+ spec = inCluster .Spec .Instrumentation .Logs
32+ }
33+
34+ // Retain logs for a short time unless specified.
35+ retention := metav1.Duration {Duration : 24 * time .Hour }
36+ if spec != nil && spec .RetentionPeriod != nil {
37+ retention = spec .RetentionPeriod .AsDuration ()
38+ }
39+
40+ // Rotate log files according to retention and name them for the OpenTelemetry Collector.
41+ //
42+ // The ".log" suffix is replaced by ".csv" for CSV log files, and
43+ // the ".log" suffix is replaced by ".json" for JSON log files.
44+ //
45+ // https://www.postgresql.org/docs/current/runtime-config-logging.html
46+ for k , v := range postgres .LogRotation (retention , "postgresql-" , ".log" ) {
47+ outParameters .Mandatory .Add (k , v )
48+ }
49+
50+ // Enable logging to file. Postgres uses a "logging collector" to safely write concurrent messages.
51+ // NOTE: That collector is designed to not lose messages. When it is overloaded, other Postgres processes block.
52+ //
53+ // https://www.postgresql.org/docs/current/runtime-config-logging.html
54+ outParameters .Mandatory .Add ("logging_collector" , "on" )
55+
56+ // PostgreSQL v8.3 adds support for CSV logging, and
57+ // PostgreSQL v15 adds support for JSON logging.
58+ // The latter is preferred because newlines are escaped as "\n", U+005C + U+006E.
59+ if version >= 15 {
60+ outParameters .Mandatory .Add ("log_destination" , "jsonlog" )
61+ } else {
62+ outParameters .Mandatory .Add ("log_destination" , "csvlog" )
63+ }
64+
65+ // Log in a timezone the OpenTelemetry Collector understands.
66+ outParameters .Mandatory .Add ("log_timezone" , "UTC" )
67+
68+ // TODO(logs): Remove this call and do it in [postgres.NewParameters] regardless of the gate.
69+ outParameters .Mandatory .Add ("log_directory" , fmt .Sprintf ("%s/logs/postgres" , postgres .DataStorage (inCluster )))
70+ }
71+ }
72+
2273func NewConfigForPostgresPod (ctx context.Context ,
2374 inCluster * v1beta1.PostgresCluster ,
24- outParameters * postgres.ParameterSet ,
75+ inParameters * postgres.ParameterSet ,
2576) * Config {
2677 config := NewConfig (inCluster .Spec .Instrumentation )
2778
@@ -30,7 +81,7 @@ func NewConfigForPostgresPod(ctx context.Context,
3081 EnablePatroniMetrics (ctx , inCluster , config )
3182
3283 // Logging
33- EnablePostgresLogging (ctx , inCluster , config , outParameters )
84+ EnablePostgresLogging (ctx , inCluster , inParameters , config )
3485 EnablePatroniLogging (ctx , inCluster , config )
3586
3687 return config
@@ -76,51 +127,18 @@ func postgresCSVNames(version int) string {
76127func EnablePostgresLogging (
77128 ctx context.Context ,
78129 inCluster * v1beta1.PostgresCluster ,
130+ inParameters * postgres.ParameterSet ,
79131 outConfig * Config ,
80- outParameters * postgres.ParameterSet ,
81132) {
82133 var spec * v1beta1.InstrumentationLogsSpec
83134 if inCluster != nil && inCluster .Spec .Instrumentation != nil {
84135 spec = inCluster .Spec .Instrumentation .Logs
85136 }
86137
87138 if OpenTelemetryLogsEnabled (ctx , inCluster ) {
88- directory := postgres . LogDirectory ( )
139+ directory := inParameters . Value ( "log_directory" )
89140 version := inCluster .Spec .PostgresVersion
90141
91- // https://www.postgresql.org/docs/current/runtime-config-logging.html
92- outParameters .Add ("logging_collector" , "on" )
93- outParameters .Add ("log_directory" , directory )
94-
95- // PostgreSQL v8.3 adds support for CSV logging, and
96- // PostgreSQL v15 adds support for JSON logging. The latter is preferred
97- // because newlines are escaped as "\n", U+005C + U+006E.
98- if version < 15 {
99- outParameters .Add ("log_destination" , "csvlog" )
100- } else {
101- outParameters .Add ("log_destination" , "jsonlog" )
102- }
103-
104- // If retentionPeriod is set in the spec, use that value; otherwise, we want
105- // to use a reasonably short duration. Defaulting to 1 day.
106- retentionPeriod := metav1.Duration {Duration : 24 * time .Hour }
107- if spec != nil && spec .RetentionPeriod != nil {
108- retentionPeriod = spec .RetentionPeriod .AsDuration ()
109- }
110-
111- // Rotate log files according to retention.
112- //
113- // The ".log" suffix is replaced by ".csv" for CSV log files, and
114- // the ".log" suffix is replaced by ".json" for JSON log files.
115- //
116- // https://www.postgresql.org/docs/current/runtime-config-logging.html
117- for k , v := range postgres .LogRotation (retentionPeriod , "postgresql-" , ".log" ) {
118- outParameters .Add (k , v )
119- }
120-
121- // Log in a timezone that the OpenTelemetry Collector will understand.
122- outParameters .Add ("log_timezone" , "UTC" )
123-
124142 // Keep track of what log records and files have been processed.
125143 // Use a subdirectory of the logs directory to stay within the same failure domain.
126144 // TODO(log-rotation): Create this directory during Collector startup.
@@ -145,8 +163,8 @@ func EnablePostgresLogging(
145163 // The 2nd through 5th fields are optional, so match through to the 7th field.
146164 // This should do a decent job of not matching the middle of some SQL statement.
147165 //
148- // The number of fields has changed over the years, but the first few
149- // are always formatted the same way .
166+ // The number of fields has changed over the years, but the first few are always formatted the same way.
167+ // [PostgreSQLParameters] ensures the timezone is UTC .
150168 //
151169 // NOTE: This regexp is invoked in multi-line mode. https://go.dev/s/re2syntax
152170 "multiline" : map [string ]string {
0 commit comments