Skip to content

Commit 1940274

Browse files
committed
Only set logging config for pgadmin when
1 parent ea3a366 commit 1940274

File tree

2 files changed

+57
-79
lines changed

2 files changed

+57
-79
lines changed

internal/controller/standalone_pgadmin/pod.go

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -379,39 +379,11 @@ func startupCommand(ctx context.Context, inPgadmin *v1beta1.PGAdmin) []string {
379379
// configDatabaseURIPath is the path for mounting the database URI connection string
380380
configDatabaseURIPathAbsolutePath = configMountPath + "/" + configDatabaseURIPath
381381
)
382-
var (
383-
maxBackupRetentionNumber = "1"
384-
// One day in minutes for pgadmin rotation
385-
pgAdminRetentionPeriod = "24 * 60"
386-
// Daily rotation for gunicorn rotation
387-
gunicornRetentionPeriod = "D"
388-
)
389-
390-
// If the OpenTelemetryLogs Feature is enabled and the user has set a retention period,
391-
// we will use those values for pgAdmin log rotation, which is otherwise managed by python.
392-
if feature.Enabled(ctx, feature.OpenTelemetryLogs) &&
393-
inPgadmin.Spec.Instrumentation != nil &&
394-
inPgadmin.Spec.Instrumentation.Logs != nil &&
395-
inPgadmin.Spec.Instrumentation.Logs.RetentionPeriod != nil {
396-
397-
retentionNumber, period := collector.ParseDurationForLogrotate(inPgadmin.Spec.Instrumentation.Logs.RetentionPeriod)
398-
// `LOG_ROTATION_MAX_LOG_FILES`` in pgadmin refers to the already rotated logs.
399-
// `backupCount` for gunicorn is similar.
400-
// Our retention unit is for total number of log files, so subtract 1 to account
401-
// for the currently-used log file.
402-
maxBackupRetentionNumber = strconv.Itoa(retentionNumber - 1)
403-
if period == "hourly" {
404-
// If the period is hourly, set the pgadmin
405-
// and gunicorn retention periods to hourly.
406-
pgAdminRetentionPeriod = "60"
407-
gunicornRetentionPeriod = "H"
408-
}
409-
}
410382

411383
// The constants set in configSystem will not be overridden through
412384
// spec.config.settings.
413385
var configSystem = `
414-
import glob, json, re, os, logging
386+
import glob, json, re, os
415387
DEFAULT_BINARY_PATHS = {'pg': sorted([''] + glob.glob('/usr/pgsql-*/bin')).pop()}
416388
with open('` + configMountPath + `/` + configFilePath + `') as _f:
417389
_conf, _data = re.compile(r'[A-Z_0-9]+'), json.load(_f)
@@ -423,18 +395,8 @@ if os.path.isfile('` + ldapPasswordAbsolutePath + `'):
423395
if os.path.isfile('` + configDatabaseURIPathAbsolutePath + `'):
424396
with open('` + configDatabaseURIPathAbsolutePath + `') as _f:
425397
CONFIG_DATABASE_URI = _f.read()
426-
427-
DATA_DIR = '` + dataMountPath + `'
428-
LOG_FILE = '` + LogFileAbsolutePath + `'
429-
LOG_ROTATION_AGE = ` + pgAdminRetentionPeriod + ` # minutes
430-
LOG_ROTATION_SIZE = 5 # MiB
431-
LOG_ROTATION_MAX_LOG_FILES = ` + maxBackupRetentionNumber + `
432-
433-
JSON_LOGGER = True
434-
CONSOLE_LOG_LEVEL = logging.WARNING
435-
FILE_LOG_LEVEL = logging.INFO
436-
FILE_LOG_FORMAT_JSON = {'time': 'created', 'name': 'name', 'level': 'levelname', 'message': 'message'}
437398
`
399+
438400
// Gunicorn reads from the `/etc/pgadmin/gunicorn_config.py` file during startup
439401
// after all other config files.
440402
// - https://docs.gunicorn.org/en/latest/configure.html#configuration-file
@@ -450,12 +412,59 @@ FILE_LOG_FORMAT_JSON = {'time': 'created', 'name': 'name', 'level': 'levelname',
450412
// https://docs.python.org/3/library/logging.html#logrecord-attributes.
451413
// JsonFormatter is used to format the log: https://pypi.org/project/jsonformatter/
452414
var gunicornConfig = `
453-
import json, re, collections, copy, gunicorn, gunicorn.glogging
415+
import json, re
454416
with open('` + configMountPath + `/` + gunicornConfigFilePath + `') as _f:
455417
_conf, _data = re.compile(r'[a-z_]+'), json.load(_f)
456418
if type(_data) is dict:
457419
globals().update({k: v for k, v in _data.items() if _conf.fullmatch(k)})
420+
`
421+
422+
// If OTel logs feature gate is enabled, we want to change the pgAdmin/gunicorn logging
423+
if feature.Enabled(ctx, feature.OpenTelemetryLogs) && inPgadmin.Spec.Instrumentation != nil {
424+
425+
var (
426+
maxBackupRetentionNumber = "1"
427+
// One day in minutes for pgadmin rotation
428+
pgAdminRetentionPeriod = "24 * 60"
429+
// Daily rotation for gunicorn rotation
430+
gunicornRetentionPeriod = "D"
431+
)
432+
433+
// If the user has set a retention period, we will use those values for log rotation,
434+
// which is otherwise managed by python.
435+
if inPgadmin.Spec.Instrumentation.Logs != nil &&
436+
inPgadmin.Spec.Instrumentation.Logs.RetentionPeriod != nil {
437+
438+
retentionNumber, period := collector.ParseDurationForLogrotate(inPgadmin.Spec.Instrumentation.Logs.RetentionPeriod)
439+
// `LOG_ROTATION_MAX_LOG_FILES`` in pgadmin refers to the already rotated logs.
440+
// `backupCount` for gunicorn is similar.
441+
// Our retention unit is for total number of log files, so subtract 1 to account
442+
// for the currently-used log file.
443+
maxBackupRetentionNumber = strconv.Itoa(retentionNumber - 1)
444+
if period == "hourly" {
445+
// If the period is hourly, set the pgadmin
446+
// and gunicorn retention periods to hourly.
447+
pgAdminRetentionPeriod = "60"
448+
gunicornRetentionPeriod = "H"
449+
}
450+
}
451+
452+
configSystem = configSystem + `
453+
import logging
454+
DATA_DIR = '` + dataMountPath + `'
455+
LOG_FILE = '` + LogFileAbsolutePath + `'
456+
LOG_ROTATION_AGE = ` + pgAdminRetentionPeriod + ` # minutes
457+
LOG_ROTATION_SIZE = 5 # MiB
458+
LOG_ROTATION_MAX_LOG_FILES = ` + maxBackupRetentionNumber + `
459+
460+
JSON_LOGGER = True
461+
CONSOLE_LOG_LEVEL = logging.WARNING
462+
FILE_LOG_LEVEL = logging.INFO
463+
FILE_LOG_FORMAT_JSON = {'time': 'created', 'name': 'name', 'level': 'levelname', 'message': 'message'}
464+
`
458465

466+
gunicornConfig = gunicornConfig + `
467+
import collections, copy, gunicorn, gunicorn.glogging
459468
gunicorn.SERVER_SOFTWARE = 'Python'
460469
logconfig_dict = copy.deepcopy(gunicorn.glogging.CONFIG_DEFAULTS)
461470
logconfig_dict['loggers']['gunicorn.access']['handlers'] = ['file']
@@ -479,6 +488,7 @@ logconfig_dict['formatters']['json'] = {
479488
])
480489
}
481490
`
491+
}
482492

483493
args := []string{strings.TrimLeft(configSystem, "\n"), strings.TrimLeft(gunicornConfig, "\n")}
484494

internal/controller/standalone_pgadmin/pod_test.go

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ initContainers:
146146
echo "$2" > /etc/pgadmin/gunicorn_config.py
147147
- startup
148148
- |
149-
import glob, json, re, os, logging
149+
import glob, json, re, os
150150
DEFAULT_BINARY_PATHS = {'pg': sorted([''] + glob.glob('/usr/pgsql-*/bin')).pop()}
151151
with open('/etc/pgadmin/conf.d/~postgres-operator/pgadmin-settings.json') as _f:
152152
_conf, _data = re.compile(r'[A-Z_0-9]+'), json.load(_f)
@@ -158,46 +158,12 @@ initContainers:
158158
if os.path.isfile('/etc/pgadmin/conf.d/~postgres-operator/config-database-uri'):
159159
with open('/etc/pgadmin/conf.d/~postgres-operator/config-database-uri') as _f:
160160
CONFIG_DATABASE_URI = _f.read()
161-
162-
DATA_DIR = '/var/lib/pgadmin'
163-
LOG_FILE = '/var/lib/pgadmin/logs/pgadmin.log'
164-
LOG_ROTATION_AGE = 24 * 60 # minutes
165-
LOG_ROTATION_SIZE = 5 # MiB
166-
LOG_ROTATION_MAX_LOG_FILES = 1
167-
168-
JSON_LOGGER = True
169-
CONSOLE_LOG_LEVEL = logging.WARNING
170-
FILE_LOG_LEVEL = logging.INFO
171-
FILE_LOG_FORMAT_JSON = {'time': 'created', 'name': 'name', 'level': 'levelname', 'message': 'message'}
172161
- |
173-
import json, re, collections, copy, gunicorn, gunicorn.glogging
162+
import json, re
174163
with open('/etc/pgadmin/conf.d/~postgres-operator/gunicorn-config.json') as _f:
175164
_conf, _data = re.compile(r'[a-z_]+'), json.load(_f)
176165
if type(_data) is dict:
177166
globals().update({k: v for k, v in _data.items() if _conf.fullmatch(k)})
178-
179-
gunicorn.SERVER_SOFTWARE = 'Python'
180-
logconfig_dict = copy.deepcopy(gunicorn.glogging.CONFIG_DEFAULTS)
181-
logconfig_dict['loggers']['gunicorn.access']['handlers'] = ['file']
182-
logconfig_dict['loggers']['gunicorn.error']['handlers'] = ['file']
183-
logconfig_dict['handlers']['file'] = {
184-
'class': 'logging.handlers.TimedRotatingFileHandler',
185-
'filename': '/var/lib/pgadmin/logs/gunicorn.log',
186-
'backupCount': 1,
187-
'interval': 1, # every one unit (defined by when), rotate
188-
'when': 'D',
189-
'formatter': 'json',
190-
}
191-
logconfig_dict['formatters']['json'] = {
192-
'class': 'jsonformatter.JsonFormatter',
193-
'separators': (',', ':'),
194-
'format': collections.OrderedDict([
195-
('time', 'created'),
196-
('name', 'name'),
197-
('level', 'levelname'),
198-
('message', 'message'),
199-
])
200-
}
201167
name: pgadmin-startup
202168
resources: {}
203169
securityContext:
@@ -381,7 +347,7 @@ initContainers:
381347
echo "$2" > /etc/pgadmin/gunicorn_config.py
382348
- startup
383349
- |
384-
import glob, json, re, os, logging
350+
import glob, json, re, os
385351
DEFAULT_BINARY_PATHS = {'pg': sorted([''] + glob.glob('/usr/pgsql-*/bin')).pop()}
386352
with open('/etc/pgadmin/conf.d/~postgres-operator/pgadmin-settings.json') as _f:
387353
_conf, _data = re.compile(r'[A-Z_0-9]+'), json.load(_f)
@@ -394,6 +360,7 @@ initContainers:
394360
with open('/etc/pgadmin/conf.d/~postgres-operator/config-database-uri') as _f:
395361
CONFIG_DATABASE_URI = _f.read()
396362
363+
import logging
397364
DATA_DIR = '/var/lib/pgadmin'
398365
LOG_FILE = '/var/lib/pgadmin/logs/pgadmin.log'
399366
LOG_ROTATION_AGE = 60 # minutes
@@ -405,12 +372,13 @@ initContainers:
405372
FILE_LOG_LEVEL = logging.INFO
406373
FILE_LOG_FORMAT_JSON = {'time': 'created', 'name': 'name', 'level': 'levelname', 'message': 'message'}
407374
- |
408-
import json, re, collections, copy, gunicorn, gunicorn.glogging
375+
import json, re
409376
with open('/etc/pgadmin/conf.d/~postgres-operator/gunicorn-config.json') as _f:
410377
_conf, _data = re.compile(r'[a-z_]+'), json.load(_f)
411378
if type(_data) is dict:
412379
globals().update({k: v for k, v in _data.items() if _conf.fullmatch(k)})
413380
381+
import collections, copy, gunicorn, gunicorn.glogging
414382
gunicorn.SERVER_SOFTWARE = 'Python'
415383
logconfig_dict = copy.deepcopy(gunicorn.glogging.CONFIG_DEFAULTS)
416384
logconfig_dict['loggers']['gunicorn.access']['handlers'] = ['file']

0 commit comments

Comments
 (0)