Skip to content

Commit

Permalink
CIVICRM_LOG_FILE - Allow constant to specify the log-file name
Browse files Browse the repository at this point in the history
Allow system administrators to define the file-naming convention for log files.

This complements on civicrm#20109, which is a step toward logging more information
to separate channels.  The primary risk of directing channels to separate
channels is that existing log-aggregators will not find them (e.g. they may
expect a consolidated log file).

This mitigate the risk by phasing-in the new filenames -- and allowing opt-ins/opt-outs.

* For new deployments, the default is `CiviCRM.{{CHANNEL}}.{{HASH}}.log`. It should be expected that
  logs will be split into multiple channels/files, and that channels/files may come and go over time.
* For sysadmins that want a single/predictable log, use `CiviCRM.{{HASH}}.log` or `CiviCRM.log`.
* For existing deployments, the default is `CiviCRM.{{LEGACY_CHANNEL}}{{LEGACY_HASH}}log`. This
  will only produce files that match the old naming convention. New channels are consolidated under
  the blank channel-name.

Before
------

Suppose you make these two log statements:

```
cv ev 'Civi::log()->info("default stuff"); Civi::log("ipn")->info("payment stuff");'
```

It will generate these two log files:

```
~/bknix/build/dmaster/web/sites/default/files/civicrm/ConfigAndLog/CiviCRM.0123abcd0123abcd99999999.log
~/bknix/build/dmaster/web/sites/default/files/civicrm/ConfigAndLog/CiviCRM.ipn.0123abcd0123abcd99999999log
```

After
-----

The behavior depends on on `CIVICRM_LOG_FILE`. Here are the log files produced by different configurations:

```
== Default on new deployments
== define('CIVICRM_LOG_FILE', 'CiviCRM.{{CHANNEL}}.{{HASH}}.log');
~/bknix/build/dmaster/web/sites/default/files/civicrm/ConfigAndLog/CiviCRM.ipn.0123abcd0123abcd99999999.log
~/bknix/build/dmaster/web/sites/default/files/civicrm/ConfigAndLog/CiviCRM.default.0123abcd0123abcd99999999.log

== Default on old/unconfigured deployments
== define('CIVICRM_LOG_FILE', 'CiviCRM.{{LEGACY_CHANNEL}}{{LEGACY_HASH}}log');
~/bknix/build/dmaster/web/sites/default/files/civicrm/ConfigAndLog/CiviCRM.0123abcd0123abcd99999999.log

== Use on combined log for everything
== define('CIVICRM_LOG_FILE', '/tmp/my-log/CiviCRM.log');
/tmp/my-log/CiviCRM.log

== Store logs in the normal `[civicrm.log]` folder, but with deep directories
== define('CIVICRM_LOG_FILE', '[civicrm.log]/{{HASH}}/{{CHANNEL}}/{{YYYY-MM-DD}}.log');
~/bknix/build/dmaster/web/sites/default/files/civicrm/ConfigAndLog/0123abcd0123abcd99999999/ipn/2021-04-27.log
~/bknix/build/dmaster/web/sites/default/files/civicrm/ConfigAndLog/0123abcd0123abcd99999999/default/2021-04-27.log

== Store logs in an alternate part of the `[civicrm.private]` folder
== define('CIVICRM_LOG_FILE', '[civicrm.private]/logging/{{HASH}}/{{CHANNEL}}/{{YYYY-MM-DD}}.log');
~/bknix/build/dmaster/web/sites/default/files/civicrm/logging/0123abcd0123abcd99999999/ipn/2021-04-27.log
~/bknix/build/dmaster/web/sites/default/files/civicrm/logging/0123abcd0123abcd99999999/default/2021-04-27.log

== Store logs in `/tmp` with long file names
== define('CIVICRM_LOG_FILE', '/tmp/my-log/civicrm-{{HASH}}-{{CHANNEL}}-{{YYYY-MM-DD}}.log');
/tmp/my-log/civicrm-0123abcd0123abcd99999999-default-2021-04-27.log
/tmp/my-log/civicrm-0123abcd0123abcd99999999-ipn-2021-04-27.log
```

You can verify this by running https://gist.github.com/totten/bd0df4478653330cf812bd481cb76ffc
  • Loading branch information
totten committed Apr 27, 2021
1 parent feb6ed8 commit 01d38fd
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 9 deletions.
25 changes: 16 additions & 9 deletions CRM/Core/Error.php
Original file line number Diff line number Diff line change
Expand Up @@ -668,15 +668,22 @@ protected static function generateLogFileName($prefix) {
if (!isset(\Civi::$statics[__CLASS__]['logger_file' . $prefix])) {
$config = CRM_Core_Config::singleton();

$prefixString = $prefix ? ($prefix . '.') : '';

if (CRM_Utils_Constant::value('CIVICRM_LOG_HASH', TRUE)) {
$hash = self::generateLogFileHash($config) . '.';
}
else {
$hash = '';
}
$fileName = $config->configAndLogDir . 'CiviCRM.' . $prefixString . $hash . 'log';
$filePat = CRM_Utils_Constant::value('CIVICRM_LOG_FILE', 'CiviCRM.{{LEGACY_CHANNEL}}{{LEGACY_HASH}}log');
$hash = self::generateLogFileHash($config);

// Before Civi::log($channel) was standardized and expanded, a handful of ext's used CRM_Core_Error::debug_log_mesage(...$prefix...).
// On legacy configurations, any unrecognized channels are consolidated into the standard log.
$legacyChannels = '/^(sql_log|org\.civicrm\.volunteer|com\.skvare\.membershipextra|GoCardless|iparl|mailchimp|mautic|senators-members-import)/';

$relFile = strtr($filePat, [
'{{CHANNEL}}' => $prefix ? $prefix : 'default',
'{{HASH}}' => $hash,
'{{LEGACY_CHANNEL}}' => preg_match($legacyChannels, $prefix) ? ($prefix . '.') : '',
'{{LEGACY_HASH}}' => CRM_Utils_Constant::value('CIVICRM_LOG_HASH', TRUE) ? ($hash . '.') : '',
'{{YYYY_MM_DD}}' => date('Y_m_d'),
'{{YYYY-MM-DD}}' => date('Y-m-d'),
]);
$fileName = $relFile[0] === '[' ? Civi::paths()->getPath($relFile) : CRM_Utils_File::absoluteDirectory($relFile, $config->configAndLogDir);

// Roll log file monthly or if greater than our threshold.
// Size-based rotation introduced in response to filesize limits on
Expand Down
28 changes: 28 additions & 0 deletions templates/CRM/common/civicrm.settings.php.template
Original file line number Diff line number Diff line change
Expand Up @@ -518,10 +518,38 @@ if (CIVICRM_UF === 'UnitTests') {
}

/**
* Define the naming convention for log files.
*
* By default, paths are relative to the standard CiviCRM log dir. However, an absolute path may be used.
*
* The following variables are accepted:
* - {{HASH}}: A unique/hard-to-guess code which identifies the deployment. Use this to mitigate the risk that logs could be leaked by a misconfigured web-server.
* - {{CHANNEL}}: The name of the log-channel. If channel is blank, use "default".
* - {{LEGACY_CHANNEL}}: (Backward compat) The name of the log-channel followed by ".". If channel is blank, then "".
* - {{LEGACY_HASH}}: (Backward compat) Depending on "CIVICRM_LOG_HASH", this is either an empty-string or HASH-plus-".".
* - {{YYYY-MM-DD}}: The current date (eg "2021-01-02")
*/
if (!defined('CIVICRM_LOG_FILE')) {
define('CIVICRM_LOG_FILE', 'CiviCRM.{{CHANNEL}}.{{HASH}}.log'); // Default on new deployments
// define('CIVICRM_LOG_FILE', 'CiviCRM.{{LEGACY_CHANNEL}}{{LEGACY_HASH}}log'); // Default on old/existing deployments
// define('CIVICRM_LOG_FILE', 'CiviCRM.{{HASH}}.log'); // Consolidate logs in one per-site/uniquely-named file.
// define('CIVICRM_LOG_FILE', '/var/log/php/CiviCRM.log'); // Consolidate logs in one file.
// define('CIVICRM_LOG_FILE', '[civicrm.log]/{{HASH}}/{{CHANNEL}}/{{YYYY-MM-DD}}.log');
// define('CIVICRM_LOG_FILE', '[cms.root]/../var/log/civicrm-{{CHANNEL}}-{{YYYY-MM-DD}}.log');
// define('CIVICRM_LOG_FILE', '/var/log/civicrm/{{HASH}}/{{CHANNEL}}-{{YYYY-MM-DD}}.log');
// define('CIVICRM_LOG_FILE', '/tmp/civicrm-{{HASH}}-{{CHANNEL}}-{{YYYY-MM-DD}}.log');
// define('CIVICRM_LOG_FILE', getenv('CIVICRM_LOG_FILE') ?: 'CiviCRM.{{HASH}}.log');
}

/**
* (Deprecated; superceded by CIVICRM_LOG_FILE)
*
* Whether to include the hash in config log filenames. Defaults to TRUE.
* Disable only if you have configured the logfiles to be outside the docroot
* using the civicrm.log path setting.
*
* This is only relevant on older deployments that lack CIVICRM_LOG_FILE.
*
*/
// if (!defined('CIVICRM_LOG_HASH')) {
// define('CIVICRM_LOG_HASH', FALSE );
Expand Down

0 comments on commit 01d38fd

Please sign in to comment.