mirror of
https://github.com/archtechx/tenancy.git
synced 2026-08-06 06:54:03 +00:00
Re-resolve all stack channels that include any of the configured channels
Reverting the LogTenancyBootstrapper changes will make the new "stack channels that include any configured channel are re-resolved" test fali
This commit is contained in:
parent
eaedd4a2e5
commit
68e6fd6c02
2 changed files with 63 additions and 19 deletions
|
|
@ -107,32 +107,37 @@ class LogTenancyBootstrapper implements TenancyBootstrapper
|
||||||
* re-resolved with the new, tenant-specific config on the next use.
|
* re-resolved with the new, tenant-specific config on the next use.
|
||||||
*
|
*
|
||||||
* Includes:
|
* Includes:
|
||||||
* - the default channel (primarily because it can be 'stack')
|
|
||||||
* - all channels in the $storagePathChannels array
|
* - all channels in the $storagePathChannels array
|
||||||
* - all channels that have custom overrides in the $channelOverrides property
|
* - all channels that have custom overrides in the $channelOverrides property
|
||||||
|
* - any 'stack' channel that includes one of the above as a member
|
||||||
|
*
|
||||||
|
* Stack channels are included because once a stack has been used, it keeps logging
|
||||||
|
* to wherever its members pointed at that moment. So a stack used in the central
|
||||||
|
* context would keep writing to the central logs, even after tenancy is initialized
|
||||||
|
* and its member channels are configured for the tenant.
|
||||||
|
* Forgetting the stack forces it to be re-resolved with its members' updated (tenant)
|
||||||
|
* config.
|
||||||
|
*
|
||||||
|
* Only stacks one level deep are handled.
|
||||||
*/
|
*/
|
||||||
protected function getChannels(): array
|
protected function getChannels(): array
|
||||||
{
|
{
|
||||||
/**
|
$configuredChannels = array_unique([
|
||||||
* Include the default channel in the list of channels to configure/re-resolve.
|
|
||||||
*
|
|
||||||
* Including the default channel is harmless (if it's not overridden and not in $storagePathChannels,
|
|
||||||
* it'll just be forgotten and re-resolved on the next use with the original config), and for the
|
|
||||||
* case where 'stack' is the default, this is necessary since the 'stack' channel will be resolved
|
|
||||||
* and saved in the log manager, and its stale config could accidentally be used instead of the stack member channels.
|
|
||||||
*
|
|
||||||
* For example, when you use 'stack' with the 'slack' channel,
|
|
||||||
* if only 'slack' is forgotten, 'stack' would still use the stale cached 'slack' driver,
|
|
||||||
* and if only 'stack' is forgotten, the 'slack' channel's config would remain unchanged (central).
|
|
||||||
*/
|
|
||||||
$defaultChannel = $this->config->get('logging.default');
|
|
||||||
|
|
||||||
return array_filter(
|
|
||||||
array_unique([
|
|
||||||
$defaultChannel,
|
|
||||||
...static::$storagePathChannels,
|
...static::$storagePathChannels,
|
||||||
...array_keys(static::$channelOverrides),
|
...array_keys(static::$channelOverrides),
|
||||||
]),
|
]);
|
||||||
|
|
||||||
|
$stackChannels = [];
|
||||||
|
|
||||||
|
foreach ($this->config->get('logging.channels') as $channel => $config) {
|
||||||
|
// Include stack channels that have at least one configured channel as a member
|
||||||
|
if (($config['driver'] ?? null) === 'stack' && array_intersect($config['channels'] ?? [], $configuredChannels)) {
|
||||||
|
$stackChannels[] = $channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_filter(
|
||||||
|
array_unique([...$configuredChannels, ...$stackChannels]),
|
||||||
fn (string $channel): bool => $this->config->has("logging.channels.{$channel}")
|
fn (string $channel): bool => $this->config->has("logging.channels.{$channel}")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -350,6 +350,45 @@ test('stack logs are written to all configured channels with tenant-specific pat
|
||||||
->not()->toContain('tenant');
|
->not()->toContain('tenant');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('stack channels that include any configured channel are re-resolved', function () {
|
||||||
|
config([
|
||||||
|
'tenancy.bootstrappers' => [
|
||||||
|
FilesystemTenancyBootstrapper::class,
|
||||||
|
LogTenancyBootstrapper::class,
|
||||||
|
],
|
||||||
|
'logging.channels.custom_stack' => [
|
||||||
|
'driver' => 'stack',
|
||||||
|
'channels' => ['single'],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$tenant = Tenant::create(['id' => 'stack-tenant']);
|
||||||
|
$centralLogPath = storage_path('logs/laravel.log');
|
||||||
|
|
||||||
|
// Resolve the stack channel in the central context first
|
||||||
|
// (this caches the stack with its members still pointing at the central logs).
|
||||||
|
Log::channel('custom_stack')->info('central');
|
||||||
|
expect(file_get_contents($centralLogPath))->toContain('central');
|
||||||
|
|
||||||
|
tenancy()->initialize($tenant);
|
||||||
|
|
||||||
|
Log::channel('custom_stack')->info('tenant log message');
|
||||||
|
|
||||||
|
// The stack channel should have been re-resolved with the
|
||||||
|
// updated (tenant) config for its member channels,
|
||||||
|
// so 'tenant log message' should be logged to the tenant log,
|
||||||
|
// not the central log.
|
||||||
|
expect(file_get_contents($centralLogPath))
|
||||||
|
->toContain('central')
|
||||||
|
->not()->toContain('tenant log message');
|
||||||
|
|
||||||
|
$tenantLogPath = storage_path('logs/laravel.log');
|
||||||
|
|
||||||
|
expect(file_exists($tenantLogPath))->toBeTrue();
|
||||||
|
expect(file_get_contents($tenantLogPath))
|
||||||
|
->toContain('tenant log message');
|
||||||
|
});
|
||||||
|
|
||||||
test('slack channel uses correct webhook urls', function () {
|
test('slack channel uses correct webhook urls', function () {
|
||||||
config([
|
config([
|
||||||
'logging.channels.slack.url' => 'central-webhook',
|
'logging.channels.slack.url' => 'central-webhook',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue