LogRotation returns parameters that rotate log files while keeping a minimum amount. Postgres truncates and reuses log files after that minimum amount. Log file names start with filePrefix and end with fileSuffix. NOTE: These parameters do *not* enable logging to files. Set "logging_collector" for
(minimum metav1.Duration, filePrefix, fileSuffix string)
| 137 | // |
| 138 | // NOTE: These parameters do *not* enable logging to files. Set "logging_collector" for that. |
| 139 | func LogRotation(minimum metav1.Duration, filePrefix, fileSuffix string) map[string]string { |
| 140 | hours := math.Ceil(minimum.Hours()) |
| 141 | |
| 142 | // The "log_filename" parameter is interpreted similar to `strftime`; |
| 143 | // escape percent U+0025 by doubling it. |
| 144 | // - https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-LOG-FILENAME |
| 145 | prefix := strings.ReplaceAll(filePrefix, "%", "%%") |
| 146 | suffix := strings.ReplaceAll(fileSuffix, "%", "%%") |
| 147 | |
| 148 | // Postgres can "rotate" its own log files by calculating log_filename as needed. |
| 149 | // However, the automated portions of log_filename are *entirely* based on time. |
| 150 | // An inappropriate pairing of log_filename with other logging parameters could lose log messages. |
| 151 | // |
| 152 | // TODO(logs): Limit the size/bytes of logs without losing messages; |
| 153 | // probably requires another process that deletes the oldest files. TODO(sidecar) |
| 154 | // |
| 155 | // The parameter combinations below have Postgres discard log messages and reuse log files |
| 156 | // only after the minimum time has elapsed. |
| 157 | |
| 158 | result := map[string]string{ |
| 159 | // Discard old messages when log_filename is reused due to rotation. |
| 160 | "log_truncate_on_rotation": "on", |
| 161 | |
| 162 | // To not lose messages, log_rotation_size must be larger than the volume of messages emitted before log_filename changes. |
| 163 | // Rather than monitor and accommodate that, disable rotation by size completely. |
| 164 | "log_rotation_size": "0", |
| 165 | } |
| 166 | |
| 167 | // These pairings have Postgres log to multiple files so a log consumer |
| 168 | // has the opportunity to read a prior file while Postgres truncates the next. |
| 169 | switch { |
| 170 | case hours <= 1: |
| 171 | // One hour of logs in minute-long files |
| 172 | result["log_filename"] = prefix + "%M" + suffix |
| 173 | result["log_rotation_age"] = "1min" |
| 174 | |
| 175 | case hours <= 24: |
| 176 | // One day of logs in hour-long files |
| 177 | result["log_filename"] = prefix + "%H" + suffix |
| 178 | result["log_rotation_age"] = "1h" |
| 179 | |
| 180 | case hours <= 24*7: |
| 181 | // One week of logs in day-long files |
| 182 | result["log_filename"] = prefix + "%a" + suffix |
| 183 | result["log_rotation_age"] = "1d" |
| 184 | |
| 185 | case hours <= 24*28: |
| 186 | // One month of logs in day-long files |
| 187 | result["log_filename"] = prefix + "%d" + suffix |
| 188 | result["log_rotation_age"] = "1d" |
| 189 | |
| 190 | default: |
| 191 | // One year of logs in day-long files |
| 192 | result["log_filename"] = prefix + "%j" + suffix |
| 193 | result["log_rotation_age"] = "1d" |
| 194 | } |
| 195 | |
| 196 | return result |
no outgoing calls