src
1 week ago
CHANGELOG.md
1 week ago
LICENSE
1 week ago
README.md
1 week ago
composer.json
1 week ago
README.md
184 lines
| 1 | # Inpsyde Logger |
| 2 | [](https://github.com/inpsyde/inpsyde-woocommerce-logging/actions/workflows/ci.yml](https://github.com/inpsyde/inpsyde-woocommerce-logging/actions/workflows/ci.yml](https://github.com/inpsyde/inpsyde-woocommerce-logging/actions/workflows/ci.yml) |
| 3 | |
| 4 | A module for [inpsyde/modularity][] providing tools for logging. Heavily based on [](https://github.com/inpsyde/product-woocommerce-logginginpsyde/product-woocommerce-logging](https://github.com/inpsyde/product-woocommerce-logging](https://github.com/inpsyde/product-woocommerce-logging). |
| 5 | |
| 6 | This module allows you to define the list of events that will be logged. As a default logger used NativePhpLogger class, |
| 7 | but it can be replaced with any other implementing `Psr\Log\LoggerInterface`. Additionally, provided PsrWcLogger class. |
| 8 | It's based on WooCommerce logging system. |
| 9 | |
| 10 | ## Installation |
| 11 | |
| 12 | The best way to install this package is through Composer: |
| 13 | |
| 14 | ```BASH |
| 15 | $ composer require inpsyde/logger |
| 16 | ``` |
| 17 | |
| 18 | ## Usage |
| 19 | |
| 20 | There are two options of package usage: event-based and direct. |
| 21 | |
| 22 | ### Event-based usage |
| 23 | *** |
| 24 | |
| 25 | Extend the `inpsyde_logger.log_events` service in your application like this: |
| 26 | |
| 27 | ```php |
| 28 | //my-plugin.php |
| 29 | 'inpsyde_logger.log_events' => function (array $existingLogEvents, \Psr\Container\ContainerInterface $container): array { |
| 30 | $logEventsToAdd = [ |
| 31 | [ |
| 32 | 'name' => 'my_app_something_failed', |
| 33 | 'log_level' => \Psr\Log\LogLevel::ERROR, |
| 34 | 'message' => 'Failed to do action, exception caught: {exception}', |
| 35 | ], |
| 36 | [ |
| 37 | 'name' => 'my_app_something_happened', |
| 38 | 'log_level' => \Psr\Log\LogLevel::INFO, |
| 39 | 'message' => 'Webhook call was received' |
| 40 | ], |
| 41 | [ |
| 42 | 'name' => 'my_app_product_added', |
| 43 | 'log_level' => \Psr\Log\LogLevel::NOTICE, |
| 44 | 'message' => function($context): string { |
| 45 | $product = $context['product']; |
| 46 | |
| 47 | return sprintf('Product with ID %1$s was added.', $product->id()); |
| 48 | } |
| 49 | ], |
| 50 | ]; |
| 51 | |
| 52 | return array_merge($existingLogEvents, $logEventsToAdd); |
| 53 | } |
| 54 | ``` |
| 55 | Note that `message` may be either string or a callable returning string. You may provide your function returning log message |
| 56 | if you want more control of the actual message producing in runtime. |
| 57 | |
| 58 | Then, dispatch an event with data required for logging: |
| 59 | |
| 60 | ```php |
| 61 | //SomePluginClass.php |
| 62 | do_action('my_app_something_failed', ['exception' => $exception]); |
| 63 | ``` |
| 64 | |
| 65 | or |
| 66 | |
| 67 | ```php |
| 68 | /** @var \Psr\EventDispatcher\EventDispatcherInterface $eventDispatcher */ |
| 69 | $eventDispatcher->dispatch((object) ['name' => 'my_app_something_failed', 'exception' => $exception]); |
| 70 | ``` |
| 71 | |
| 72 | ### Direct usage of Logger |
| 73 | *** |
| 74 | You can use the logger directly, like this: |
| 75 | |
| 76 | ```php |
| 77 | /** @var \Psr\Log\LoggerInterface $logger */ |
| 78 | $logger = $container->get('inpsyde_logger.logger'); |
| 79 | $logger->info('Hi! This is the log message with {your-placeholder}.', ['your-placeholder' => 'placeholder content']); |
| 80 | ``` |
| 81 | |
| 82 | ### Adding context |
| 83 | *** |
| 84 | As you may notice, both usage examples included context array with placeholder, and its actual value. |
| 85 | Context array is optional in both cases. Both will produce the same log entry: |
| 86 | ``` |
| 87 | Hi! This is the log message with placeholder content. |
| 88 | ``` |
| 89 | |
| 90 | If you want to, you can set default source of logs, so it can be added to each entry if none provided per request. To do so, declare service `inpsyde_logger.log_events`. |
| 91 | For example: |
| 92 | ```php |
| 93 | //PluginCore.php |
| 94 | class PluginCore implements \Inpsyde\Modularity\Module\ExtendingModule { |
| 95 | public function extensions() : array{ |
| 96 | return [ |
| 97 | //your core module services here |
| 98 | 'inpsyde_logger.logging_source' => 'My awesome plugin name' |
| 99 | ]; |
| 100 | } |
| 101 | } |
| 102 | ``` |
| 103 | |
| 104 | Default source of logs can be overridden for any log entry by adding `source` element to your `context` array like this: |
| 105 | ```php |
| 106 | // If using PsrWcLogger source from the context will be used automatically. |
| 107 | $logger->info( |
| 108 | 'Hi! This is the log message with {your-placeholder}.', |
| 109 | [ |
| 110 | 'your-placeholder' => 'placeholder content', |
| 111 | 'source' => 'My app' |
| 112 | ] |
| 113 | ); |
| 114 | ``` |
| 115 | |
| 116 | Adding `source` to the `context` without respective placeholder in the message will work if you are using |
| 117 | `PsrWcLogger` (default) as a logger class. Otherwise, you need to add `source` as a placeholder with some source as a value. |
| 118 | For example: |
| 119 | ```php |
| 120 | //If using logger class other than PsrWcLogger: |
| 121 | $logger->info( |
| 122 | '{source}: Hi! This is the log message with {your-placeholder}.', |
| 123 | [ |
| 124 | 'your-placeholder' => 'placeholder content', |
| 125 | 'source' => 'My app' |
| 126 | ] |
| 127 | ); |
| 128 | ``` |
| 129 | |
| 130 | ### Logging complex data |
| 131 | |
| 132 | Using the variable interpolation mechanisms described above works well enough for scalar data and `stringable` objects, but has some pitfalls with |
| 133 | more complex objects. |
| 134 | |
| 135 | ```php |
| 136 | assert($wcOrder instanceof WC_Order); |
| 137 | $logger->info('Failed to create payload from order: {order}', ['order' => $wcOrder]); |
| 138 | ``` |
| 139 | You would not usually want to bloat up your business logic with the peculiarities of turning a `WC_Order` object into a meaningful yet compact |
| 140 | log message. At the same time, the logging module cannot possibly be aware of every object that exists in your application. |
| 141 | To solve this problem, the module can be configured with object formatters. It uses a map to determine which formatter to use for a given object type: |
| 142 | |
| 143 | ```php |
| 144 | 'inpsyde_logger.object_formatter.map' => |
| 145 | static function (ContainerInterface $container): array { |
| 146 | return [ |
| 147 | Throwable::class => $container->get('inpsyde_logger.object_formatter.map.exception'), |
| 148 | ]; |
| 149 | }, |
| 150 | ``` |
| 151 | Via service extensions, you can add formatters for any object type. |
| 152 | If none is found, a default is used that checks if there is a `__toString` method. |
| 153 | |
| 154 | ## Development |
| 155 | |
| 156 | 1. Run `make setup` to setup Docker and install dependencies. |
| 157 | 2. Run `make lint test` to run linter and tests. |
| 158 | |
| 159 | See [](/MakefileMakefile](/Makefile](/Makefile) for other useful commands. |
| 160 | |
| 161 | The [](/.env.example.env](/.env.example](/.env.example) file contains some configuration of the Docker environment. |
| 162 | You may need to rebuild Docker for changes (like WP version) to take effect: `make destroy setup` (all WP data will be lost). |
| 163 | |
| 164 | For Windows users: `make` is not included out-of-the-box but you can simply copy the commands from [](/MakefileMakefile](/Makefile](/Makefile) to `cmd`, |
| 165 | e.g. `docker-compose run --rm test vendor/bin/phpunit` instead of `make test`. |
| 166 | |
| 167 | ## Crafted by Inpsyde |
| 168 | |
| 169 | The team at [Inpsyde][] is engineering the Web since 2006. |
| 170 | |
| 171 | ## License |
| 172 | |
| 173 | This module is provided under the [](https://opensource.org/licenses/gpl-2.0.phpGPLv2](https://opensource.org/licenses/gpl-2.0.php](https://opensource.org/licenses/gpl-2.0.php) license. |
| 174 | |
| 175 | |
| 176 | ## Contributing |
| 177 | |
| 178 | All feedback / bug reports / pull requests are welcome. |
| 179 | |
| 180 | [inpsyde/modularity]: https://github.com/inpsyde/modularity |
| 181 | [wp-events]: https://github.com/inpsyde/wp-events |
| 182 | [container-interop/service-provider]: https://github.com/container-interop/service-provider |
| 183 | [Inpsyde]: https://inpsyde.com |
| 184 |