Complex classes like Logger often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Logger, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 22 | class Logger extends AbstractLogger { |
||
| 23 | const CONFIG_NAME = 'mongodb_watchdog.settings'; |
||
| 24 | |||
| 25 | const TRACKER_COLLECTION = 'watchdog_tracker'; |
||
| 26 | const TEMPLATE_COLLECTION = 'watchdog'; |
||
| 27 | const EVENT_COLLECTION_PREFIX = 'watchdog_event_'; |
||
| 28 | const EVENT_COLLECTIONS_PATTERN = '^watchdog_event_[[:xdigit:]]{32}$'; |
||
| 29 | |||
| 30 | const LEGACY_TYPE_MAP = [ |
||
| 31 | 'typeMap' => [ |
||
| 32 | 'array' => 'array', |
||
| 33 | 'document' => 'array', |
||
| 34 | 'root' => 'array', |
||
| 35 | ], |
||
| 36 | ]; |
||
| 37 | |||
| 38 | /** |
||
| 39 | * The logger storage. |
||
| 40 | * |
||
| 41 | * @var \MongoDB\Database |
||
| 42 | */ |
||
| 43 | protected $database; |
||
| 44 | |||
| 45 | /** |
||
| 46 | * The limit for the capped event collections. |
||
| 47 | * |
||
| 48 | * @var int |
||
| 49 | */ |
||
| 50 | protected $items; |
||
| 51 | |||
| 52 | /** |
||
| 53 | * The minimum logging level. |
||
| 54 | * |
||
| 55 | * @var int |
||
| 56 | * |
||
| 57 | * @see https://drupal.org/node/1355808 |
||
| 58 | */ |
||
| 59 | protected $limit = RfcLogLevel::DEBUG; |
||
| 60 | |||
| 61 | /** |
||
| 62 | * The message's placeholders parser. |
||
| 63 | * |
||
| 64 | * @var \Drupal\Core\Logger\LogMessageParserInterface |
||
| 65 | */ |
||
| 66 | protected $parser; |
||
| 67 | |||
| 68 | /** |
||
| 69 | * The "requests" setting. |
||
| 70 | * |
||
| 71 | * @var int |
||
| 72 | */ |
||
| 73 | protected $requests; |
||
| 74 | |||
| 75 | /** |
||
| 76 | * The request_stack service. |
||
| 77 | * |
||
| 78 | * @var \Symfony\Component\HttpFoundation\RequestStack |
||
| 79 | */ |
||
| 80 | protected $requestStack; |
||
| 81 | |||
| 82 | /** |
||
| 83 | * An array of templates already used in this request. |
||
| 84 | * |
||
| 85 | * Used only with request tracking enabled. |
||
| 86 | * |
||
| 87 | * @var string[] |
||
| 88 | */ |
||
| 89 | protected $templates = []; |
||
| 90 | |||
| 91 | /** |
||
| 92 | * A sequence number for log events during a request. |
||
| 93 | * |
||
| 94 | * @var int |
||
| 95 | */ |
||
| 96 | protected $sequence = 0; |
||
| 97 | |||
| 98 | /** |
||
| 99 | * Logger constructor. |
||
| 100 | * |
||
| 101 | * @param \MongoDB\Database $database |
||
| 102 | * The database object. |
||
| 103 | * @param \Drupal\Core\Logger\LogMessageParserInterface $parser |
||
| 104 | * The parser to use when extracting message variables. |
||
| 105 | * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory |
||
| 106 | * The core config_factory service. |
||
| 107 | * @param \Symfony\Component\HttpFoundation\RequestStack $stack |
||
| 108 | * The core request_stack service. |
||
| 109 | */ |
||
| 110 | public function __construct(Database $database, LogMessageParserInterface $parser, ConfigFactoryInterface $config_factory, RequestStack $stack) { |
||
| 121 | |||
| 122 | /** |
||
| 123 | * Fill in the log_entry function, file, and line. |
||
| 124 | * |
||
| 125 | * @param array $log_entry |
||
| 126 | * An event information to be logger. |
||
| 127 | * @param array $backtrace |
||
| 128 | * A call stack. |
||
| 129 | */ |
||
| 130 | protected function enhanceLogEntry(array &$log_entry, array $backtrace) { |
||
| 177 | |||
| 178 | /** |
||
| 179 | * {@inheritdoc} |
||
| 180 | * |
||
| 181 | * @see https://drupal.org/node/1355808 |
||
| 182 | */ |
||
| 183 | public function log($level, $template, array $context = []) { |
||
| 288 | |||
| 289 | /** |
||
| 290 | * Ensure a collection is capped with the proper size. |
||
| 291 | * |
||
| 292 | * @param string $name |
||
| 293 | * The collection name. |
||
| 294 | * @param int $inboundSize |
||
| 295 | * The collection size cap. |
||
| 296 | * |
||
| 297 | * @return \MongoDB\Collection |
||
| 298 | * The collection, usable for additional commands like index creation. |
||
| 299 | * |
||
| 300 | * @TODO support sharded clusters: convertToCapped does not support them. |
||
| 301 | * |
||
| 302 | * @see https://docs.mongodb.com/manual/reference/command/convertToCapped |
||
| 303 | * |
||
| 304 | * Note that MongoDB 3.2 still misses a proper exists() command, which is the |
||
| 305 | * reason for the weird try/catch logic. |
||
| 306 | * |
||
| 307 | * @see https://jira.mongodb.org/browse/SERVER-1938 |
||
| 308 | */ |
||
| 309 | public function ensureCappedCollection($name, $inboundSize) { |
||
| 348 | |||
| 349 | /** |
||
| 350 | * Ensure indexes are set on the collections and tracker collection is capped. |
||
| 351 | * |
||
| 352 | * First index is on <line, timestamp> instead of <function, line, timestamp>, |
||
| 353 | * because we write to this collection a lot, and the smaller index on two |
||
| 354 | * numbers should be much faster to create than one with a string included. |
||
| 355 | */ |
||
| 356 | public function ensureSchema() { |
||
| 400 | |||
| 401 | /** |
||
| 402 | * Return a collection, given its template id. |
||
| 403 | * |
||
| 404 | * @param string $template_id |
||
| 405 | * The string representation of a template \MongoId. |
||
| 406 | * |
||
| 407 | * @return \MongoDB\Collection |
||
| 408 | * A collection object for the specified template id. |
||
| 409 | */ |
||
| 410 | public function eventCollection($template_id) { |
||
| 420 | |||
| 421 | /** |
||
| 422 | * List the event collections. |
||
| 423 | * |
||
| 424 | * @return \MongoDB\Collection[] |
||
| 425 | * The collections with a name matching the event pattern. |
||
| 426 | */ |
||
| 427 | public function eventCollections() { |
||
| 436 | |||
| 437 | /** |
||
| 438 | * Return the number of events for a template. |
||
| 439 | * |
||
| 440 | * @param \Drupal\mongodb_watchdog\EventTemplate $template |
||
| 441 | * A template for which to count events. |
||
| 442 | * |
||
| 443 | * @return int |
||
| 444 | * The number of matching events. |
||
| 445 | */ |
||
| 446 | public function eventCount(EventTemplate $template) { |
||
| 449 | |||
| 450 | /** |
||
| 451 | * Return the events having occurred during a given request. |
||
| 452 | * |
||
| 453 | * @param string $requestId |
||
| 454 | * The request unique_id. |
||
| 455 | * @param int $skip |
||
| 456 | * The number of events to skip in the result. |
||
| 457 | * @param int $limit |
||
| 458 | * The maximum number of events to return. |
||
| 459 | * |
||
| 460 | * @return array<\Drupal\mongodb_watchdog\EventTemplate\Drupal\mongodb_watchdog\Event[]> |
||
| 461 | * An array of [template, event] arrays, ordered by occurrence order. |
||
| 462 | */ |
||
| 463 | public function requestEvents($requestId, $skip = 0, $limit = 0) { |
||
| 500 | |||
| 501 | /** |
||
| 502 | * Count events matching a request unique_id. |
||
| 503 | * |
||
| 504 | * XXX This implementation may be very inefficient in case of a request gone |
||
| 505 | * bad generating non-templated varying messages: #requests is O(#templates). |
||
| 506 | * |
||
| 507 | * @param string $requestId |
||
| 508 | * The unique_id of the request. |
||
| 509 | * |
||
| 510 | * @return int |
||
| 511 | * The number of events matching the unique_id. |
||
| 512 | */ |
||
| 513 | public function requestEventsCount($requestId) { |
||
| 530 | |||
| 531 | /** |
||
| 532 | * Return the number of event templates. |
||
| 533 | */ |
||
| 534 | public function templatesCount() { |
||
| 537 | |||
| 538 | /** |
||
| 539 | * Return an array of templates uses during a given request. |
||
| 540 | * |
||
| 541 | * @param string $unsafe_request_id |
||
| 542 | * A request "unique_id". |
||
| 543 | * |
||
| 544 | * @return \Drupal\mongodb_watchdog\EventTemplate[] |
||
| 545 | * An array of EventTemplate instances. |
||
| 546 | */ |
||
| 547 | public function requestTemplates($unsafe_request_id) { |
||
| 585 | |||
| 586 | /** |
||
| 587 | * Return the request events tracker collection. |
||
| 588 | * |
||
| 589 | * @return \MongoDB\Collection |
||
| 590 | * The collection. |
||
| 591 | */ |
||
| 592 | public function trackerCollection() { |
||
| 595 | |||
| 596 | /** |
||
| 597 | * Return the event templates collection. |
||
| 598 | * |
||
| 599 | * @return \MongoDB\Collection |
||
| 600 | * The collection. |
||
| 601 | */ |
||
| 602 | public function templateCollection() { |
||
| 605 | |||
| 606 | /** |
||
| 607 | * Return templates matching type and level criteria. |
||
| 608 | * |
||
| 609 | * @param string[] $types |
||
| 610 | * An array of EventTemplate types. May be a hash. |
||
| 611 | * @param string[]|int[] $levels |
||
| 612 | * An array of severity levels. |
||
| 613 | * @param int $skip |
||
| 614 | * The number of templates to skip before the first one displayed. |
||
| 615 | * @param int $limit |
||
| 616 | * The maximum number of templates to return. |
||
| 617 | * |
||
| 618 | * @return \MongoDB\Driver\Cursor |
||
| 619 | * A query result for the templates. |
||
| 620 | */ |
||
| 621 | public function templates(array $types = [], array $levels = [], $skip = 0, $limit = 0) { |
||
| 651 | |||
| 652 | /** |
||
| 653 | * Return the template types actually present in storage. |
||
| 654 | * |
||
| 655 | * @return string[] |
||
| 656 | * An array of distinct EventTemplate types. |
||
| 657 | */ |
||
| 658 | public function templateTypes() { |
||
| 662 | |||
| 663 | } |
||
| 664 |
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: