-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTraceableNetwork.php
127 lines (110 loc) · 3.38 KB
/
TraceableNetwork.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<?php
/*
* This file is part of the phpflo/phpflo-flowtrace package.
*
* (c) Marc Aschmann <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace PhpFlo\FlowTrace;
use PhpFlo\Core\AbstractNetworkDecorator;
use PhpFlo\Common\NetworkInterface;
use Psr\Log\LoggerInterface;
/**
* Network for tracing events.
*
* @package PhpFlo\FlowTrace
* @author Marc Aschmann <[email protected]>
*/
class TraceableNetwork extends AbstractNetworkDecorator implements NetworkInterface
{
const TYPE_DATA = 'data';
const TYPE_CONNECT = 'connect';
const TYPE_DISCONNECT = 'disconnect';
const TYPE_BEGIN_GROUP = 'begin.group';
const TYPE_END_GROUP = 'end.group';
/**
* @var array
*/
private $actions;
/**
* @var LoggerInterface
*/
private $logger;
/**
* TraceableNetwork constructor.
*
* @param NetworkInterface $network
* @param LoggerInterface $logger
*/
public function __construct(NetworkInterface $network, LoggerInterface $logger)
{
parent::__construct($network);
$this->actions = [
self::TYPE_DATA => 'DATA',
self::TYPE_CONNECT => 'CONN',
self::TYPE_DISCONNECT => 'DISC'
];
$this->logger = $logger;
$this->network->hook(self::TYPE_DATA, 'flowtrace', $this->trace(self::TYPE_DATA));
$this->network->hook(self::TYPE_CONNECT, 'flowtrace', $this->trace(self::TYPE_CONNECT));
$this->network->hook(self::TYPE_DISCONNECT, 'flowtrace', $this->trace(self::TYPE_DISCONNECT));
}
/**
* Wrap the creation of the callback
*
* @param string $type
* @return \Closure
*/
private function trace(string $type): \Closure
{
$trace = function() use ($type) {
switch ($type) {
case TraceableNetwork::TYPE_DATA:
$this->traceData(func_get_args(), $type);
break;
case TraceableNetwork::TYPE_CONNECT:
case TraceableNetwork::TYPE_DISCONNECT:
$this->traceAction(func_get_args(), $type);
break;
}
};
return $trace->bindTo($this);
}
/**
* @param array $args
* @param string $type
*/
private function traceData(array $args, string $type)
{
$data = $args[0];
$socket = $args[1];
if (!is_string($data)) {
$data = serialize($data);
}
$to = $socket->to();
$message = "-> {$to['port']} {$to['process']['id']}";
$from = $socket->from();
if (isset($from['process'])) {
$message = " {$from['process']['id']} {$from['port']} {$message}";
}
$this->logger->info("{$message} {$this->actions[$type]} {$data}");
}
/**
* @param array $args
* @param string $type
*/
private function traceAction(array $args, string $type)
{
$socket = $args[0];
$to = $socket->to();
$message = "-> {$to['port']} {$to['process']['id']}";
$from = $socket->from();
if (isset($from['process'])) {
$message = " {$from['process']['id']} {$from['port']} {$message}";
}
$this->logger->debug("{$message} {$this->actions[$type]}");
}
}