PluginProbe
DecaLog / 4.4.0
DecaLog v4.4.0
3.0.2 3.1.0 3.10.0 3.2.0 3.3.0 3.4.0 3.4.1 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.6.3 3.7.0 3.7.1 3.8.0 3.9.0 3.9.1 4.0.0 4.1.0 4.2.0 4.3.0 4.3.1 4.4.0 4.5.0 All 75 releases
decalog / includes / handlers / class-sharedmemoryhandler.php

class-sharedmemoryhandler.php in DecaLog 4.4.0, at includes/handlers/class-sharedmemoryhandler.php

145 lines 3.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Shared memory handler for Monolog
4 *
5 * Handles all features of shared memory handler for Monolog.
6 *
7 * @package Handlers
8 * @author Pierre Lannoy <https://pierre.lannoy.fr/>.
9 * @since 2.0.0
10 */
11
12 namespace Decalog\Handler;
13
14 use Decalog\System\Option;
15 use DLMonolog\Logger;
16 use DLMonolog\Handler\AbstractProcessingHandler;
17 use DLMonolog\Formatter\FormatterInterface;
18 use Decalog\Formatter\GenericFormatter;
19 use Decalog\System\SharedMemory;
20 use Decalog\System\Environment;
21 use malkusch\lock\mutex\FlockMutex;
22 use malkusch\lock\mutex\SemaphoreMutex;
23
24 /**
25 * Define the Monolog shared memory handler.
26 *
27 * Handles all features of shared memory handler for Monolog.
28 *
29 * @package Handlers
30 * @author Pierre Lannoy <https://pierre.lannoy.fr/>.
31 * @since 2.0.0
32 */
33 class SharedMemoryHandler extends AbstractProcessingHandler {
34
35 /**
36 * The buffer size.
37 *
38 * @since 2.0.0
39 * @var integer $buffer The number of messages in buffer.
40 */
41 private $buffer = 4000;
42
43 /**
44 * The read index.
45 *
46 * @since 2.0.0
47 * @var string $index The index for data.
48 */
49 private static $index = '';
50
51 /**
52 * Get relevant ftok.
53 *
54 * @since 2.0.0
55 */
56 private static function ftok() {
57 if ( 1 === Environment::exec_mode() ) {
58 return ftok( __FILE__, 'c' );
59 } else {
60 return ftok( __FILE__, 'w' );
61 }
62 }
63
64 /**
65 * Initialize the class and set its properties.
66 *
67 * @param integer $level Optional. The min level to log.
68 * @param boolean $bubble Optional. Has the record to bubble?.
69 * @since 2.0.0
70 */
71 public function __construct( $level = Logger::INFO, bool $bubble = true ) {
72 parent::__construct( $level, $bubble );
73 }
74
75 /**
76 * {@inheritDoc}
77 */
78 protected function getDefaultFormatter(): FormatterInterface {
79 return new GenericFormatter();
80 }
81
82 /**
83 * Write the record in memory.
84 *
85 * @param array $record The record to write.
86 * @since 2.0.0
87 */
88 protected function write( array $record ): void {
89 // phpcs:ignore
90 $messages = unserialize( $record['formatted'] );
91 $mutex = new FlockMutex( fopen( __FILE__, 'r' ), 1 );
92 $ftok = self::ftok();
93 $mutex->synchronized(function () use ($messages, $ftok) {
94 $sm = new SharedMemory( $ftok );
95 $data = $sm->read();
96 foreach ( $messages as $message ) {
97 if ( is_array( $message ) ) {
98 $date = new \DateTime();
99 $data[ $date->format( 'YmdHisu' ) ] = $message;
100 }
101 }
102 $data = array_slice( $data, -$this->buffer );
103 if ( false === $sm->write( $data ) ) {
104 //error_log( 'ERROR' );
105 }
106 });
107 }
108
109 /**
110 * Read the current records.
111 *
112 * @return array The current records, ordered.
113 * @since 2.0.0
114 */
115 public static function read(): array {
116 try {
117 $mutex = new FlockMutex( fopen( __FILE__, 'r' ), 1 );
118 $ftok = ftok( __FILE__, 'w' );
119 $data1 = $mutex->synchronized(function () use ($ftok) {
120 $log = new SharedMemory( $ftok );
121 $data = $log->read();
122 return $data;
123 });
124 $ftok = ftok( __FILE__, 'c' );
125 $data2 = $mutex->synchronized(function () use ($ftok) {
126 $log = new SharedMemory( $ftok );
127 $data = $log->read();
128 return $data;
129 });
130 $data = array_merge( $data1, $data2 );
131 uksort($data, 'strcmp' );
132 } catch ( \Throwable $e ) {
133 $data = [];
134 }
135 $result = [];
136 foreach ( $data as $key => $line ) {
137 if ( 0 < strcmp( $key, self::$index ) ) {
138 $result[$key] = $line;
139 self::$index = $key;
140 }
141 }
142 return $result;
143 }
144 }
145