| 129 | } |
| 130 | |
| 131 | func EnablePostgresLogging( |
| 132 | ctx context.Context, |
| 133 | inCluster *v1beta1.PostgresCluster, |
| 134 | inParameters *postgres.ParameterSet, |
| 135 | outConfig *Config, |
| 136 | ) { |
| 137 | if OpenTelemetryLogsEnabled(ctx, inCluster) { |
| 138 | spec := inCluster.Spec.Instrumentation |
| 139 | directory := inParameters.Value("log_directory") |
| 140 | version := inCluster.Spec.PostgresVersion |
| 141 | |
| 142 | // Keep track of what log records and files have been processed. |
| 143 | // Use a subdirectory of the logs directory to stay within the same failure domain. |
| 144 | // TODO(log-rotation): Create this directory during Collector startup. |
| 145 | // |
| 146 | // https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/-/extension/storage/filestorage#readme |
| 147 | outConfig.Extensions["file_storage/postgres_logs"] = map[string]any{ |
| 148 | "directory": directory + "/receiver", |
| 149 | "create_directory": true, |
| 150 | "fsync": true, |
| 151 | } |
| 152 | |
| 153 | // TODO(postgres-14): We can stop parsing CSV logs when 14 is EOL. |
| 154 | // https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/-/receiver/filelogreceiver#readme |
| 155 | outConfig.Receivers["filelog/postgres_csvlog"] = map[string]any{ |
| 156 | // Read the CSV files and keep track of what has been processed. |
| 157 | // The wildcard covers all potential log file names. |
| 158 | "include": []string{directory + "/*.csv"}, |
| 159 | "storage": "file_storage/postgres_logs", |
| 160 | |
| 161 | // Postgres does not escape newlines in its CSV log format. Search for |
| 162 | // the beginning of every record, starting with an unquoted timestamp. |
| 163 | // The 2nd through 5th fields are optional, so match through to the 7th field. |
| 164 | // This should do a decent job of not matching the middle of some SQL statement. |
| 165 | // |
| 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. |
| 168 | // |
| 169 | // NOTE: This regexp is invoked in multi-line mode. https://go.dev/s/re2syntax |
| 170 | "multiline": map[string]string{ |
| 171 | "line_start_pattern": `^\d{4}-\d\d-\d\d \d\d:\d\d:\d\d.\d{3} UTC` + // 1st: timestamp |
| 172 | `,(?:"[_\D](?:[^"]|"")*")?` + // 2nd: user name |
| 173 | `,(?:"[_\D](?:[^"]|"")*")?` + // 3rd: database name |
| 174 | `,\d*,(?:"(?:[^"]|"")+")?` + // 4–5th: process id, connection |
| 175 | `,[0-9a-f]+[.][0-9a-f]+,\d+,`, // 6–7th: session id, session line |
| 176 | }, |
| 177 | |
| 178 | // Differentiate these from the JSON ones below. |
| 179 | "operators": []map[string]any{ |
| 180 | {"type": "move", "from": "body", "to": "body.original"}, |
| 181 | {"type": "add", "field": "body.format", "value": "csv"}, |
| 182 | {"type": "add", "field": "body.headers", "value": postgresCSVNames(version)}, |
| 183 | }, |
| 184 | } |
| 185 | |
| 186 | // https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/-/receiver/filelogreceiver#readme |
| 187 | outConfig.Receivers["filelog/postgres_jsonlog"] = map[string]any{ |
| 188 | // Read the JSON files and keep track of what has been processed. |