├── .gitattributes
├── .gitignore
├── Applications
├── HttpServer
│ ├── HttpServer.php
│ ├── config
│ │ ├── autoload.php
│ │ ├── config.php
│ │ ├── database.php
│ │ ├── mimes.php
│ │ └── redis.php
│ ├── controllers
│ │ └── Test.php
│ ├── core
│ │ └── Base_Controller.php
│ ├── libraries
│ │ └── Doer
│ │ │ └── DoerError.php
│ ├── start_http_server.php
│ └── system
│ │ ├── core
│ │ ├── Common.php
│ │ ├── Config.php
│ │ ├── Controller.php
│ │ ├── Input.php
│ │ ├── Loader.php
│ │ ├── Log.php
│ │ ├── Model.php
│ │ ├── Output.php
│ │ └── Security.php
│ │ └── database
│ │ ├── DB.php
│ │ ├── DB_active_rec.php
│ │ ├── DB_cache.php
│ │ ├── DB_driver.php
│ │ ├── DB_forge.php
│ │ ├── DB_query_builder.php
│ │ ├── DB_result.php
│ │ ├── DB_utility.php
│ │ ├── drivers
│ │ ├── cubrid
│ │ │ ├── cubrid_driver.php
│ │ │ ├── cubrid_forge.php
│ │ │ ├── cubrid_result.php
│ │ │ ├── cubrid_utility.php
│ │ │ └── index.html
│ │ ├── ibase
│ │ │ ├── ibase_driver.php
│ │ │ ├── ibase_forge.php
│ │ │ ├── ibase_result.php
│ │ │ ├── ibase_utility.php
│ │ │ └── index.html
│ │ ├── index.html
│ │ ├── mssql
│ │ │ ├── index.html
│ │ │ ├── mssql_driver.php
│ │ │ ├── mssql_forge.php
│ │ │ ├── mssql_result.php
│ │ │ └── mssql_utility.php
│ │ ├── mysql
│ │ │ ├── index.html
│ │ │ ├── mysql_driver.php
│ │ │ ├── mysql_forge.php
│ │ │ ├── mysql_result.php
│ │ │ └── mysql_utility.php
│ │ ├── mysqli
│ │ │ ├── index.html
│ │ │ ├── mysqli_driver.php
│ │ │ ├── mysqli_forge.php
│ │ │ ├── mysqli_result.php
│ │ │ └── mysqli_utility.php
│ │ ├── oci8
│ │ │ ├── index.html
│ │ │ ├── oci8_driver.php
│ │ │ ├── oci8_forge.php
│ │ │ ├── oci8_result.php
│ │ │ └── oci8_utility.php
│ │ ├── odbc
│ │ │ ├── index.html
│ │ │ ├── odbc_driver.php
│ │ │ ├── odbc_forge.php
│ │ │ ├── odbc_result.php
│ │ │ └── odbc_utility.php
│ │ ├── pdo
│ │ │ ├── index.html
│ │ │ ├── pdo_driver.php
│ │ │ ├── pdo_forge.php
│ │ │ ├── pdo_result.php
│ │ │ ├── pdo_utility.php
│ │ │ └── subdrivers
│ │ │ │ ├── index.html
│ │ │ │ ├── pdo_4d_driver.php
│ │ │ │ ├── pdo_4d_forge.php
│ │ │ │ ├── pdo_cubrid_driver.php
│ │ │ │ ├── pdo_cubrid_forge.php
│ │ │ │ ├── pdo_dblib_driver.php
│ │ │ │ ├── pdo_dblib_forge.php
│ │ │ │ ├── pdo_firebird_driver.php
│ │ │ │ ├── pdo_firebird_forge.php
│ │ │ │ ├── pdo_ibm_driver.php
│ │ │ │ ├── pdo_ibm_forge.php
│ │ │ │ ├── pdo_informix_driver.php
│ │ │ │ ├── pdo_informix_forge.php
│ │ │ │ ├── pdo_mysql_driver.php
│ │ │ │ ├── pdo_mysql_forge.php
│ │ │ │ ├── pdo_oci_driver.php
│ │ │ │ ├── pdo_oci_forge.php
│ │ │ │ ├── pdo_odbc_driver.php
│ │ │ │ ├── pdo_odbc_forge.php
│ │ │ │ ├── pdo_pgsql_driver.php
│ │ │ │ ├── pdo_pgsql_forge.php
│ │ │ │ ├── pdo_sqlite_driver.php
│ │ │ │ ├── pdo_sqlite_forge.php
│ │ │ │ ├── pdo_sqlsrv_driver.php
│ │ │ │ └── pdo_sqlsrv_forge.php
│ │ ├── postgre
│ │ │ ├── index.html
│ │ │ ├── postgre_driver.php
│ │ │ ├── postgre_forge.php
│ │ │ ├── postgre_result.php
│ │ │ └── postgre_utility.php
│ │ ├── sqlite
│ │ │ ├── index.html
│ │ │ ├── sqlite_driver.php
│ │ │ ├── sqlite_forge.php
│ │ │ ├── sqlite_result.php
│ │ │ └── sqlite_utility.php
│ │ ├── sqlite3
│ │ │ ├── index.html
│ │ │ ├── sqlite3_driver.php
│ │ │ ├── sqlite3_forge.php
│ │ │ ├── sqlite3_result.php
│ │ │ └── sqlite3_utility.php
│ │ └── sqlsrv
│ │ │ ├── index.html
│ │ │ ├── sqlsrv_driver.php
│ │ │ ├── sqlsrv_forge.php
│ │ │ ├── sqlsrv_result.php
│ │ │ └── sqlsrv_utility.php
│ │ └── index.html
└── Logger
│ └── start_logger.php
├── GatewayWorker
├── BusinessWorker.php
├── Gateway.php
├── Lib
│ ├── Context.php
│ ├── Db.php
│ ├── DbConnection.php
│ └── Gateway.php
├── Protocols
│ └── GatewayProtocol.php
└── Register.php
├── Logger
├── Autoloader.php
├── Client.php
├── Monolog
│ ├── ErrorHandler.php
│ ├── Formatter
│ │ ├── ChromePHPFormatter.php
│ │ ├── ElasticaFormatter.php
│ │ ├── FlowdockFormatter.php
│ │ ├── FluentdFormatter.php
│ │ ├── FormatterInterface.php
│ │ ├── GelfMessageFormatter.php
│ │ ├── HtmlFormatter.php
│ │ ├── JsonFormatter.php
│ │ ├── LineFormatter.php
│ │ ├── LogglyFormatter.php
│ │ ├── LogstashFormatter.php
│ │ ├── MongoDBFormatter.php
│ │ ├── NormalizerFormatter.php
│ │ ├── ScalarFormatter.php
│ │ └── WildfireFormatter.php
│ ├── Handler
│ │ ├── AbstractHandler.php
│ │ ├── AbstractProcessingHandler.php
│ │ ├── AbstractSyslogHandler.php
│ │ ├── AmqpHandler.php
│ │ ├── BrowserConsoleHandler.php
│ │ ├── BufferHandler.php
│ │ ├── ChromePHPHandler.php
│ │ ├── CouchDBHandler.php
│ │ ├── CubeHandler.php
│ │ ├── Curl
│ │ │ └── Util.php
│ │ ├── DeduplicationHandler.php
│ │ ├── DoctrineCouchDBHandler.php
│ │ ├── DynamoDbHandler.php
│ │ ├── ElasticSearchHandler.php
│ │ ├── ErrorLogHandler.php
│ │ ├── FilterHandler.php
│ │ ├── FingersCrossed
│ │ │ ├── ActivationStrategyInterface.php
│ │ │ ├── ChannelLevelActivationStrategy.php
│ │ │ └── ErrorLevelActivationStrategy.php
│ │ ├── FingersCrossedHandler.php
│ │ ├── FirePHPHandler.php
│ │ ├── FleepHookHandler.php
│ │ ├── FlowdockHandler.php
│ │ ├── FormattableHandlerInterface.php
│ │ ├── FormattableHandlerTrait.php
│ │ ├── GelfHandler.php
│ │ ├── GroupHandler.php
│ │ ├── Handler.php
│ │ ├── HandlerInterface.php
│ │ ├── HandlerWrapper.php
│ │ ├── HipChatHandler.php
│ │ ├── IFTTTHandler.php
│ │ ├── LogEntriesHandler.php
│ │ ├── LogglyHandler.php
│ │ ├── MailHandler.php
│ │ ├── MandrillHandler.php
│ │ ├── MissingExtensionException.php
│ │ ├── MongoDBHandler.php
│ │ ├── NativeMailerHandler.php
│ │ ├── NewRelicHandler.php
│ │ ├── NullHandler.php
│ │ ├── PHPConsoleHandler.php
│ │ ├── ProcessableHandlerInterface.php
│ │ ├── ProcessableHandlerTrait.php
│ │ ├── PsrHandler.php
│ │ ├── PushoverHandler.php
│ │ ├── RavenHandler.php
│ │ ├── RedisHandler.php
│ │ ├── RollbarHandler.php
│ │ ├── RotatingFileHandler.php
│ │ ├── SamplingHandler.php
│ │ ├── SlackHandler.php
│ │ ├── SocketHandler.php
│ │ ├── StreamHandler.php
│ │ ├── SwiftMailerHandler.php
│ │ ├── SyslogHandler.php
│ │ ├── SyslogUdp
│ │ │ └── UdpSocket.php
│ │ ├── SyslogUdpHandler.php
│ │ ├── TestHandler.php
│ │ ├── WhatFailureGroupHandler.php
│ │ └── ZendMonitorHandler.php
│ ├── Logger.php
│ ├── Processor
│ │ ├── GitProcessor.php
│ │ ├── IntrospectionProcessor.php
│ │ ├── MemoryPeakUsageProcessor.php
│ │ ├── MemoryProcessor.php
│ │ ├── MemoryUsageProcessor.php
│ │ ├── ProcessIdProcessor.php
│ │ ├── PsrLogMessageProcessor.php
│ │ ├── TagProcessor.php
│ │ ├── UidProcessor.php
│ │ └── WebProcessor.php
│ └── Registry.php
├── Psr
│ └── Log
│ │ ├── LogLevel.php
│ │ ├── LoggerAwareInterface.php
│ │ └── LoggerInterface.php
└── Server.php
├── README.md
├── Workerman
├── .gitignore
├── Autoloader.php
├── Connection
│ ├── AsyncTcpConnection.php
│ ├── ConnectionInterface.php
│ ├── TcpConnection.php
│ └── UdpConnection.php
├── Events
│ ├── Ev.php
│ ├── Event.php
│ ├── EventInterface.php
│ ├── Libevent.php
│ └── Select.php
├── Lib
│ ├── Constants.php
│ └── Timer.php
├── MIT-LICENSE.txt
├── Protocols
│ ├── Frame.php
│ ├── Http.php
│ ├── Http
│ │ └── mime.types
│ ├── ProtocolInterface.php
│ ├── Text.php
│ ├── Websocket.php
│ └── Ws.php
├── README.md
├── WebServer.php
├── Worker.php
└── composer.json
└── start.php
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Folder config file
6 | Desktop.ini
7 |
8 | # Recycle Bin used on file shares
9 | $RECYCLE.BIN/
10 |
11 | # Windows Installer files
12 | *.cab
13 | *.msi
14 | *.msm
15 | *.msp
16 |
17 | # Windows shortcuts
18 | *.lnk
19 |
20 | # =========================
21 | # Operating System Files
22 | # =========================
23 |
24 | # OSX
25 | # =========================
26 |
27 | .DS_Store
28 | .AppleDouble
29 | .LSOverride
30 |
31 | # Thumbnails
32 | ._*
33 |
34 | # Files that might appear in the root of a volume
35 | .DocumentRevisions-V100
36 | .fseventsd
37 | .Spotlight-V100
38 | .TemporaryItems
39 | .Trashes
40 | .VolumeIcon.icns
41 |
42 | # Directories potentially created on remote AFP share
43 | .AppleDB
44 | .AppleDesktop
45 | Network Trash Folder
46 | Temporary Items
47 | .apdisk
48 |
--------------------------------------------------------------------------------
/Applications/HttpServer/config/autoload.php:
--------------------------------------------------------------------------------
1 | '112.124.234.121',
9 | 'username' => 'test',
10 | 'password' => 'test',
11 | 'database' => 'test',
12 | 'dbdriver' => 'mysqli',
13 | 'dbprefix' => '',
14 | 'pconnect' => TRUE,
15 | 'db_debug' => TRUE,
16 | 'cache_on' => FALSE,
17 | 'cachedir' => '',
18 | 'char_set' => 'utf8mb4',
19 | 'dbcollat' => 'utf8_general_ci',
20 | 'swap_pre' => '',
21 | 'autoinit' => TRUE,
22 | 'stricton' => FALSE,
23 | 'compress' => TRUE
24 | );
25 |
26 |
27 | /* Location: ./application/config/database.php */
--------------------------------------------------------------------------------
/Applications/HttpServer/config/redis.php:
--------------------------------------------------------------------------------
1 | output_json(1,1);
25 | }
26 | }
--------------------------------------------------------------------------------
/Applications/HttpServer/libraries/Doer/DoerError.php:
--------------------------------------------------------------------------------
1 | others = $others;
144 | }
145 | }
146 |
147 |
--------------------------------------------------------------------------------
/Applications/HttpServer/start_http_server.php:
--------------------------------------------------------------------------------
1 | input = get_instance()->input;
27 | $this->output = get_instance()->output;
28 | $this->load = get_instance()->load;
29 | }
30 |
31 | /**
32 | * 每次访问方法都会执行这里
33 | */
34 | public function __CI_construct(){
35 |
36 | }
37 | public function __get($name)
38 | {
39 | return get_instance()->$name;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/core/Model.php:
--------------------------------------------------------------------------------
1 | $key;
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/cubrid/cubrid_utility.php:
--------------------------------------------------------------------------------
1 | db->data_cache['db_names']))
57 | {
58 | return $this->db->data_cache['db_names'];
59 | }
60 |
61 | return $this->db->data_cache['db_names'] = cubrid_list_dbs($this->db->conn_id);
62 | }
63 |
64 | // --------------------------------------------------------------------
65 |
66 | /**
67 | * CUBRID Export
68 | *
69 | * @param array Preferences
70 | * @return mixed
71 | */
72 | protected function _backup($params = array())
73 | {
74 | // No SQL based support in CUBRID as of version 8.4.0. Database or
75 | // table backup can be performed using CUBRID Manager
76 | // database administration tool.
77 | return $this->db->display_error('db_unsupported_feature');
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/cubrid/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/ibase/ibase_utility.php:
--------------------------------------------------------------------------------
1 | db->hostname, $this->db->username, $this->db->password))
58 | {
59 | $res = ibase_backup($service, $this->db->database, $filename.'.fbk');
60 |
61 | // Close the service connection
62 | ibase_service_detach($service);
63 | return $res;
64 | }
65 |
66 | return FALSE;
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/ibase/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/mssql/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/mssql/mssql_utility.php:
--------------------------------------------------------------------------------
1 | db->display_error('db_unsupported_feature');
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/mysql/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/mysqli/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/oci8/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/oci8/oci8_utility.php:
--------------------------------------------------------------------------------
1 | db->display_error('db_unsupported_feature');
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/odbc/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/odbc/odbc_forge.php:
--------------------------------------------------------------------------------
1 | db->display_error('db_unsupported_feature');
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/pdo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/pdo/pdo_forge.php:
--------------------------------------------------------------------------------
1 | db->display_error('db_unsupported_feature');
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/pdo/subdrivers/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/pdo/subdrivers/pdo_odbc_forge.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/postgre/postgre_utility.php:
--------------------------------------------------------------------------------
1 | db->display_error('db_unsupported_feature');
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/sqlite/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/sqlite/sqlite_utility.php:
--------------------------------------------------------------------------------
1 | db->display_error('db_unsupported_feature');
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/sqlite3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/sqlite3/sqlite3_utility.php:
--------------------------------------------------------------------------------
1 | db->display_error('db_unsupported_feature');
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/sqlsrv/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/drivers/sqlsrv/sqlsrv_utility.php:
--------------------------------------------------------------------------------
1 | db->display_error('db_unsupported_feature');
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/Applications/HttpServer/system/database/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Applications/Logger/start_logger.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace GatewayWorker\Lib;
15 |
16 | use Exception;
17 |
18 | /**
19 | * 上下文 包含当前用户 uid, 内部通信 local_ip local_port socket_id,以及客户端 client_ip client_port
20 | */
21 | class Context
22 | {
23 | /**
24 | * 内部通讯 id
25 | *
26 | * @var string
27 | */
28 | public static $local_ip;
29 |
30 | /**
31 | * 内部通讯端口
32 | *
33 | * @var int
34 | */
35 | public static $local_port;
36 |
37 | /**
38 | * 客户端 ip
39 | *
40 | * @var string
41 | */
42 | public static $client_ip;
43 |
44 | /**
45 | * 客户端端口
46 | *
47 | * @var int
48 | */
49 | public static $client_port;
50 |
51 | /**
52 | * client_id
53 | *
54 | * @var string
55 | */
56 | public static $client_id;
57 |
58 | /**
59 | * 连接 connection->id
60 | *
61 | * @var int
62 | */
63 | public static $connection_id;
64 |
65 | /**
66 | * 旧的session
67 | *
68 | * @var string
69 | */
70 | public static $old_session;
71 |
72 | /**
73 | * 编码 session
74 | *
75 | * @param mixed $session_data
76 | * @return string
77 | */
78 | public static function sessionEncode($session_data = '')
79 | {
80 | if ($session_data !== '') {
81 | return serialize($session_data);
82 | }
83 | return '';
84 | }
85 |
86 | /**
87 | * 解码 session
88 | *
89 | * @param string $session_buffer
90 | * @return mixed
91 | */
92 | public static function sessionDecode($session_buffer)
93 | {
94 | return unserialize($session_buffer);
95 | }
96 |
97 | /**
98 | * 清除上下文
99 | *
100 | * @return void
101 | */
102 | public static function clear()
103 | {
104 | self::$local_ip = self::$local_port = self::$client_ip = self::$client_port =
105 | self::$client_id = self::$connection_id = self::$old_session = null;
106 | }
107 |
108 | /**
109 | * 通讯地址到 client_id 的转换
110 | *
111 | * @param int $local_ip
112 | * @param int $local_port
113 | * @param int $connection_id
114 | * @return string
115 | */
116 | public static function addressToClientId($local_ip, $local_port, $connection_id)
117 | {
118 | return bin2hex(pack('NnN', $local_ip, $local_port, $connection_id));
119 | }
120 |
121 | /**
122 | * client_id 到通讯地址的转换
123 | *
124 | * @param string $client_id
125 | * @return array
126 | * @throws Exception
127 | */
128 | public static function clientIdToAddress($client_id)
129 | {
130 | if (strlen($client_id) !== 20) {
131 | throw new Exception("client_id $client_id is invalid");
132 | }
133 | return unpack('Nlocal_ip/nlocal_port/Nconnection_id', pack('H*', $client_id));
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/GatewayWorker/Lib/Db.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace GatewayWorker\Lib;
15 |
16 | use Config\Db as DbConfig;
17 | use Exception;
18 |
19 | /**
20 | * 数据库类
21 | */
22 | class Db
23 | {
24 | /**
25 | * 实例数组
26 | *
27 | * @var array
28 | */
29 | protected static $instance = array();
30 |
31 | /**
32 | * 获取实例
33 | *
34 | * @param string $config_name
35 | * @return DbConnection
36 | * @throws Exception
37 | */
38 | public static function instance($config_name)
39 | {
40 | if (!isset(DbConfig::$$config_name)) {
41 | echo "\\Config\\Db::$config_name not set\n";
42 | throw new Exception("\\Config\\Db::$config_name not set\n");
43 | }
44 |
45 | if (empty(self::$instance[$config_name])) {
46 | $config = DbConfig::$$config_name;
47 | self::$instance[$config_name] = new DbConnection($config['host'], $config['port'],
48 | $config['user'], $config['password'], $config['dbname']);
49 | }
50 | return self::$instance[$config_name];
51 | }
52 |
53 | /**
54 | * 关闭数据库实例
55 | *
56 | * @param string $config_name
57 | */
58 | public static function close($config_name)
59 | {
60 | if (isset(self::$instance[$config_name])) {
61 | self::$instance[$config_name]->closeConnection();
62 | self::$instance[$config_name] = null;
63 | }
64 | }
65 |
66 | /**
67 | * 关闭所有数据库实例
68 | */
69 | public static function closeAll()
70 | {
71 | foreach (self::$instance as $connection) {
72 | $connection->closeConnection();
73 | }
74 | self::$instance = array();
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/Logger/Autoloader.php:
--------------------------------------------------------------------------------
1 | $logger_name,
88 | 'logger_level' => $logger_level,
89 | 'logger_message' => $logger_message
90 | ) ));
91 | return self::sendData(self::$address, $bin_data);
92 | }
93 |
94 | /**
95 | * 发送数据给logger系统
96 | * @param string $address
97 | * @param string $buffer
98 | * @return boolean
99 | */
100 | public static function sendData($address, $buffer)
101 | {
102 | $socket = stream_socket_client($address);
103 | if(!$socket)
104 | {
105 | return false;
106 | }
107 | return stream_socket_sendto($socket, $buffer) == strlen($buffer);
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/Logger/Monolog/Formatter/ChromePHPFormatter.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Formatter;
13 |
14 | use Monolog\Logger;
15 |
16 | /**
17 | * Formats a log message according to the ChromePHP array format
18 | *
19 | * @author Christophe Coevoet
20 | */
21 | class ChromePHPFormatter implements FormatterInterface
22 | {
23 | /**
24 | * Translates Monolog log levels to Wildfire levels.
25 | */
26 | private $logLevels = array(
27 | Logger::DEBUG => 'log',
28 | Logger::INFO => 'info',
29 | Logger::NOTICE => 'info',
30 | Logger::WARNING => 'warn',
31 | Logger::ERROR => 'error',
32 | Logger::CRITICAL => 'error',
33 | Logger::ALERT => 'error',
34 | Logger::EMERGENCY => 'error',
35 | );
36 |
37 | /**
38 | * {@inheritdoc}
39 | */
40 | public function format(array $record)
41 | {
42 | // Retrieve the line and file if set and remove them from the formatted extra
43 | $backtrace = 'unknown';
44 | if (isset($record['extra']['file'], $record['extra']['line'])) {
45 | $backtrace = $record['extra']['file'].' : '.$record['extra']['line'];
46 | unset($record['extra']['file'], $record['extra']['line']);
47 | }
48 |
49 | $message = array('message' => $record['message']);
50 | if ($record['context']) {
51 | $message['context'] = $record['context'];
52 | }
53 | if ($record['extra']) {
54 | $message['extra'] = $record['extra'];
55 | }
56 | if (count($message) === 1) {
57 | $message = reset($message);
58 | }
59 |
60 | return array(
61 | $record['channel'],
62 | $message,
63 | $backtrace,
64 | $this->logLevels[$record['level']],
65 | );
66 | }
67 |
68 | public function formatBatch(array $records)
69 | {
70 | $formatted = array();
71 |
72 | foreach ($records as $record) {
73 | $formatted[] = $this->format($record);
74 | }
75 |
76 | return $formatted;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/Logger/Monolog/Formatter/ElasticaFormatter.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Formatter;
13 |
14 | use Elastica\Document;
15 |
16 | /**
17 | * Format a log message into an Elastica Document
18 | *
19 | * @author Jelle Vink
20 | */
21 | class ElasticaFormatter extends NormalizerFormatter
22 | {
23 | /**
24 | * @var string Elastic search index name
25 | */
26 | protected $index;
27 |
28 | /**
29 | * @var string Elastic search document type
30 | */
31 | protected $type;
32 |
33 | /**
34 | * @param string $index Elastic Search index name
35 | * @param string $type Elastic Search document type
36 | */
37 | public function __construct($index, $type)
38 | {
39 | // elasticsearch requires a ISO 8601 format date with optional millisecond precision.
40 | parent::__construct('Y-m-d\TH:i:s.uP');
41 |
42 | $this->index = $index;
43 | $this->type = $type;
44 | }
45 |
46 | /**
47 | * {@inheritdoc}
48 | */
49 | public function format(array $record)
50 | {
51 | $record = parent::format($record);
52 |
53 | return $this->getDocument($record);
54 | }
55 |
56 | /**
57 | * Getter index
58 | * @return string
59 | */
60 | public function getIndex()
61 | {
62 | return $this->index;
63 | }
64 |
65 | /**
66 | * Getter type
67 | * @return string
68 | */
69 | public function getType()
70 | {
71 | return $this->type;
72 | }
73 |
74 | /**
75 | * Convert a log message into an Elastica Document
76 | *
77 | * @param array $record Log message
78 | * @return Document
79 | */
80 | protected function getDocument($record)
81 | {
82 | $document = new Document();
83 | $document->setData($record);
84 | $document->setType($this->type);
85 | $document->setIndex($this->index);
86 |
87 | return $document;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/Logger/Monolog/Formatter/FlowdockFormatter.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Formatter;
13 |
14 | /**
15 | * formats the record to be used in the FlowdockHandler
16 | *
17 | * @author Dominik Liebler
18 | */
19 | class FlowdockFormatter implements FormatterInterface
20 | {
21 | /**
22 | * @var string
23 | */
24 | private $source;
25 |
26 | /**
27 | * @var string
28 | */
29 | private $sourceEmail;
30 |
31 | /**
32 | * @param string $source
33 | * @param string $sourceEmail
34 | */
35 | public function __construct($source, $sourceEmail)
36 | {
37 | $this->source = $source;
38 | $this->sourceEmail = $sourceEmail;
39 | }
40 |
41 | /**
42 | * {@inheritdoc}
43 | */
44 | public function format(array $record)
45 | {
46 | $tags = array(
47 | '#logs',
48 | '#' . strtolower($record['level_name']),
49 | '#' . $record['channel'],
50 | );
51 |
52 | foreach ($record['extra'] as $value) {
53 | $tags[] = '#' . $value;
54 | }
55 |
56 | $subject = sprintf(
57 | 'in %s: %s - %s',
58 | $this->source,
59 | $record['level_name'],
60 | $this->getShortMessage($record['message'])
61 | );
62 |
63 | $record['flowdock'] = array(
64 | 'source' => $this->source,
65 | 'from_address' => $this->sourceEmail,
66 | 'subject' => $subject,
67 | 'content' => $record['message'],
68 | 'tags' => $tags,
69 | 'project' => $this->source,
70 | );
71 |
72 | return $record;
73 | }
74 |
75 | /**
76 | * {@inheritdoc}
77 | */
78 | public function formatBatch(array $records)
79 | {
80 | $formatted = array();
81 |
82 | foreach ($records as $record) {
83 | $formatted[] = $this->format($record);
84 | }
85 |
86 | return $formatted;
87 | }
88 |
89 | /**
90 | * @param string $message
91 | *
92 | * @return string
93 | */
94 | public function getShortMessage($message)
95 | {
96 | static $hasMbString;
97 |
98 | if (null === $hasMbString) {
99 | $hasMbString = function_exists('mb_strlen');
100 | }
101 |
102 | $maxLength = 45;
103 |
104 | if ($hasMbString) {
105 | if (mb_strlen($message, 'UTF-8') > $maxLength) {
106 | $message = mb_substr($message, 0, $maxLength - 4, 'UTF-8') . ' ...';
107 | }
108 | } else {
109 | if (strlen($message) > $maxLength) {
110 | $message = substr($message, 0, $maxLength - 4) . ' ...';
111 | }
112 | }
113 |
114 | return $message;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/Logger/Monolog/Formatter/FluentdFormatter.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Formatter;
13 |
14 | /**
15 | * Class FluentdFormatter
16 | *
17 | * Serializes a log message to Fluentd unix socket protocol
18 | *
19 | * Fluentd config:
20 | *
21 | *
22 | * type unix
23 | * path /var/run/td-agent/td-agent.sock
24 | *
25 | *
26 | * Monolog setup:
27 | *
28 | * $logger = new Monolog\Logger('fluent.tag');
29 | * $fluentHandler = new Monolog\Handler\SocketHandler('unix:///var/run/td-agent/td-agent.sock');
30 | * $fluentHandler->setFormatter(new Monolog\Formatter\FluentdFormatter());
31 | * $logger->pushHandler($fluentHandler);
32 | *
33 | * @author Andrius Putna
34 | */
35 | class FluentdFormatter implements FormatterInterface
36 | {
37 | /**
38 | * @var bool $levelTag should message level be a part of the fluentd tag
39 | */
40 | protected $levelTag = false;
41 |
42 | public function __construct($levelTag = false)
43 | {
44 | if (!function_exists('json_encode')) {
45 | throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s FluentdUnixFormatter');
46 | }
47 |
48 | $this->levelTag = (bool) $levelTag;
49 | }
50 |
51 | public function isUsingLevelsInTag()
52 | {
53 | return $this->levelTag;
54 | }
55 |
56 | public function format(array $record)
57 | {
58 | $tag = $record['channel'];
59 | if ($this->levelTag) {
60 | $tag .= '.' . strtolower($record['level_name']);
61 | }
62 |
63 | $message = array(
64 | 'message' => $record['message'],
65 | 'extra' => $record['extra'],
66 | );
67 |
68 | if (!$this->levelTag) {
69 | $message['level'] = $record['level'];
70 | $message['level_name'] = $record['level_name'];
71 | }
72 |
73 | return json_encode(array($tag, $record['datetime']->getTimestamp(), $message));
74 | }
75 |
76 | public function formatBatch(array $records)
77 | {
78 | $message = '';
79 | foreach ($records as $record) {
80 | $message .= $this->format($record);
81 | }
82 |
83 | return $message;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Logger/Monolog/Formatter/FormatterInterface.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Formatter;
13 |
14 | /**
15 | * Interface for formatters
16 | *
17 | * @author Jordi Boggiano
18 | */
19 | interface FormatterInterface
20 | {
21 | /**
22 | * Formats a log record.
23 | *
24 | * @param array $record A record to format
25 | * @return mixed The formatted record
26 | */
27 | public function format(array $record);
28 |
29 | /**
30 | * Formats a set of log records.
31 | *
32 | * @param array $records A set of records to format
33 | * @return mixed The formatted set of records
34 | */
35 | public function formatBatch(array $records);
36 | }
37 |
--------------------------------------------------------------------------------
/Logger/Monolog/Formatter/LogglyFormatter.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Formatter;
13 |
14 | /**
15 | * Encodes message information into JSON in a format compatible with Loggly.
16 | *
17 | * @author Adam Pancutt
18 | */
19 | class LogglyFormatter extends JsonFormatter
20 | {
21 | /**
22 | * Overrides the default batch mode to new lines for compatibility with the
23 | * Loggly bulk API.
24 | *
25 | * @param int $batchMode
26 | */
27 | public function __construct($batchMode = self::BATCH_MODE_NEWLINES, $appendNewline = false)
28 | {
29 | parent::__construct($batchMode, $appendNewline);
30 | }
31 |
32 | /**
33 | * Appends the 'timestamp' parameter for indexing by Loggly.
34 | *
35 | * @see https://www.loggly.com/docs/automated-parsing/#json
36 | * @see \Monolog\Formatter\JsonFormatter::format()
37 | */
38 | public function format(array $record)
39 | {
40 | if (isset($record["datetime"]) && ($record["datetime"] instanceof \DateTime)) {
41 | $record["timestamp"] = $record["datetime"]->format("Y-m-d\TH:i:s.uO");
42 | unset($record["datetime"]);
43 | }
44 |
45 | return parent::format($record);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Logger/Monolog/Formatter/ScalarFormatter.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Formatter;
13 |
14 | /**
15 | * Formats data into an associative array of scalar values.
16 | * Objects and arrays will be JSON encoded.
17 | *
18 | * @author Andrew Lawson
19 | */
20 | class ScalarFormatter extends NormalizerFormatter
21 | {
22 | /**
23 | * {@inheritdoc}
24 | */
25 | public function format(array $record)
26 | {
27 | foreach ($record as $key => $value) {
28 | $record[$key] = $this->normalizeValue($value);
29 | }
30 |
31 | return $record;
32 | }
33 |
34 | /**
35 | * @param mixed $value
36 | * @return mixed
37 | */
38 | protected function normalizeValue($value)
39 | {
40 | $normalized = $this->normalize($value);
41 |
42 | if (is_array($normalized) || is_object($normalized)) {
43 | return $this->toJson($normalized, true);
44 | }
45 |
46 | return $normalized;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Logger/Monolog/Formatter/WildfireFormatter.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Formatter;
13 |
14 | use Monolog\Logger;
15 |
16 | /**
17 | * Serializes a log message according to Wildfire's header requirements
18 | *
19 | * @author Eric Clemmons (@ericclemmons)
20 | * @author Christophe Coevoet
21 | * @author Kirill chEbba Chebunin
22 | */
23 | class WildfireFormatter extends NormalizerFormatter
24 | {
25 | const TABLE = 'table';
26 |
27 | /**
28 | * Translates Monolog log levels to Wildfire levels.
29 | */
30 | private $logLevels = array(
31 | Logger::DEBUG => 'LOG',
32 | Logger::INFO => 'INFO',
33 | Logger::NOTICE => 'INFO',
34 | Logger::WARNING => 'WARN',
35 | Logger::ERROR => 'ERROR',
36 | Logger::CRITICAL => 'ERROR',
37 | Logger::ALERT => 'ERROR',
38 | Logger::EMERGENCY => 'ERROR',
39 | );
40 |
41 | /**
42 | * {@inheritdoc}
43 | */
44 | public function format(array $record)
45 | {
46 | // Retrieve the line and file if set and remove them from the formatted extra
47 | $file = $line = '';
48 | if (isset($record['extra']['file'])) {
49 | $file = $record['extra']['file'];
50 | unset($record['extra']['file']);
51 | }
52 | if (isset($record['extra']['line'])) {
53 | $line = $record['extra']['line'];
54 | unset($record['extra']['line']);
55 | }
56 |
57 | $record = $this->normalize($record);
58 | $message = array('message' => $record['message']);
59 | $handleError = false;
60 | if ($record['context']) {
61 | $message['context'] = $record['context'];
62 | $handleError = true;
63 | }
64 | if ($record['extra']) {
65 | $message['extra'] = $record['extra'];
66 | $handleError = true;
67 | }
68 | if (count($message) === 1) {
69 | $message = reset($message);
70 | }
71 |
72 | if (isset($record['context'][self::TABLE])) {
73 | $type = 'TABLE';
74 | $label = $record['channel'] .': '. $record['message'];
75 | $message = $record['context'][self::TABLE];
76 | } else {
77 | $type = $this->logLevels[$record['level']];
78 | $label = $record['channel'];
79 | }
80 |
81 | // Create JSON object describing the appearance of the message in the console
82 | $json = $this->toJson(array(
83 | array(
84 | 'Type' => $type,
85 | 'File' => $file,
86 | 'Line' => $line,
87 | 'Label' => $label,
88 | ),
89 | $message,
90 | ), $handleError);
91 |
92 | // The message itself is a serialization of the above JSON object + it's length
93 | return sprintf(
94 | '%s|%s|',
95 | strlen($json),
96 | $json
97 | );
98 | }
99 |
100 | public function formatBatch(array $records)
101 | {
102 | throw new \BadMethodCallException('Batch formatting does not make sense for the WildfireFormatter');
103 | }
104 |
105 | protected function normalize($data)
106 | {
107 | if (is_object($data) && !$data instanceof \DateTime) {
108 | return $data;
109 | }
110 |
111 | return parent::normalize($data);
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/AbstractHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Logger;
15 |
16 | /**
17 | * Base Handler class providing basic level/bubble support
18 | *
19 | * @author Jordi Boggiano
20 | */
21 | abstract class AbstractHandler extends Handler
22 | {
23 | protected $level = Logger::DEBUG;
24 | protected $bubble = true;
25 |
26 | /**
27 | * @param int $level The minimum logging level at which this handler will be triggered
28 | * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
29 | */
30 | public function __construct($level = Logger::DEBUG, $bubble = true)
31 | {
32 | $this->setLevel($level);
33 | $this->bubble = $bubble;
34 | }
35 |
36 | /**
37 | * {@inheritdoc}
38 | */
39 | public function isHandling(array $record): bool
40 | {
41 | return $record['level'] >= $this->level;
42 | }
43 |
44 | /**
45 | * Sets minimum logging level at which this handler will be triggered.
46 | *
47 | * @param int|string $level Level or level name
48 | * @return self
49 | */
50 | public function setLevel($level): self
51 | {
52 | $this->level = Logger::toMonologLevel($level);
53 |
54 | return $this;
55 | }
56 |
57 | /**
58 | * Gets minimum logging level at which this handler will be triggered.
59 | *
60 | * @return int
61 | */
62 | public function getLevel(): int
63 | {
64 | return $this->level;
65 | }
66 |
67 | /**
68 | * Sets the bubbling behavior.
69 | *
70 | * @param Boolean $bubble true means that this handler allows bubbling.
71 | * false means that bubbling is not permitted.
72 | * @return self
73 | */
74 | public function setBubble(bool $bubble): self
75 | {
76 | $this->bubble = $bubble;
77 |
78 | return $this;
79 | }
80 |
81 | /**
82 | * Gets the bubbling behavior.
83 | *
84 | * @return Boolean true means that this handler allows bubbling.
85 | * false means that bubbling is not permitted.
86 | */
87 | public function getBubble(): bool
88 | {
89 | return $this->bubble;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/AbstractProcessingHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | /**
15 | * Base Handler class providing the Handler structure
16 | *
17 | * Classes extending it should (in most cases) only implement write($record)
18 | *
19 | * @author Jordi Boggiano
20 | * @author Christophe Coevoet
21 | */
22 | abstract class AbstractProcessingHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface
23 | {
24 | use ProcessableHandlerTrait;
25 | use FormattableHandlerTrait;
26 |
27 | /**
28 | * {@inheritdoc}
29 | */
30 | public function handle(array $record): bool
31 | {
32 | if (!$this->isHandling($record)) {
33 | return false;
34 | }
35 |
36 | if ($this->processors) {
37 | $record = $this->processRecord($record);
38 | }
39 |
40 | $record['formatted'] = $this->getFormatter()->format($record);
41 |
42 | $this->write($record);
43 |
44 | return false === $this->bubble;
45 | }
46 |
47 | /**
48 | * Writes the record down to the log of the implementing handler
49 | *
50 | * @param array $record
51 | * @return void
52 | */
53 | abstract protected function write(array $record);
54 | }
55 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/AbstractSyslogHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Logger;
15 | use Monolog\Formatter\FormatterInterface;
16 | use Monolog\Formatter\LineFormatter;
17 |
18 | /**
19 | * Common syslog functionality
20 | */
21 | abstract class AbstractSyslogHandler extends AbstractProcessingHandler
22 | {
23 | protected $facility;
24 |
25 | /**
26 | * Translates Monolog log levels to syslog log priorities.
27 | */
28 | protected $logLevels = array(
29 | Logger::DEBUG => LOG_DEBUG,
30 | Logger::INFO => LOG_INFO,
31 | Logger::NOTICE => LOG_NOTICE,
32 | Logger::WARNING => LOG_WARNING,
33 | Logger::ERROR => LOG_ERR,
34 | Logger::CRITICAL => LOG_CRIT,
35 | Logger::ALERT => LOG_ALERT,
36 | Logger::EMERGENCY => LOG_EMERG,
37 | );
38 |
39 | /**
40 | * List of valid log facility names.
41 | */
42 | protected $facilities = array(
43 | 'auth' => LOG_AUTH,
44 | 'authpriv' => LOG_AUTHPRIV,
45 | 'cron' => LOG_CRON,
46 | 'daemon' => LOG_DAEMON,
47 | 'kern' => LOG_KERN,
48 | 'lpr' => LOG_LPR,
49 | 'mail' => LOG_MAIL,
50 | 'news' => LOG_NEWS,
51 | 'syslog' => LOG_SYSLOG,
52 | 'user' => LOG_USER,
53 | 'uucp' => LOG_UUCP,
54 | );
55 |
56 | /**
57 | * @param mixed $facility
58 | * @param int $level The minimum logging level at which this handler will be triggered
59 | * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
60 | */
61 | public function __construct($facility = LOG_USER, $level = Logger::DEBUG, $bubble = true)
62 | {
63 | parent::__construct($level, $bubble);
64 |
65 | if (!defined('PHP_WINDOWS_VERSION_BUILD')) {
66 | $this->facilities['local0'] = LOG_LOCAL0;
67 | $this->facilities['local1'] = LOG_LOCAL1;
68 | $this->facilities['local2'] = LOG_LOCAL2;
69 | $this->facilities['local3'] = LOG_LOCAL3;
70 | $this->facilities['local4'] = LOG_LOCAL4;
71 | $this->facilities['local5'] = LOG_LOCAL5;
72 | $this->facilities['local6'] = LOG_LOCAL6;
73 | $this->facilities['local7'] = LOG_LOCAL7;
74 | } else {
75 | $this->facilities['local0'] = 128; // LOG_LOCAL0
76 | $this->facilities['local1'] = 136; // LOG_LOCAL1
77 | $this->facilities['local2'] = 144; // LOG_LOCAL2
78 | $this->facilities['local3'] = 152; // LOG_LOCAL3
79 | $this->facilities['local4'] = 160; // LOG_LOCAL4
80 | $this->facilities['local5'] = 168; // LOG_LOCAL5
81 | $this->facilities['local6'] = 176; // LOG_LOCAL6
82 | $this->facilities['local7'] = 184; // LOG_LOCAL7
83 | }
84 |
85 | // convert textual description of facility to syslog constant
86 | if (array_key_exists(strtolower($facility), $this->facilities)) {
87 | $facility = $this->facilities[strtolower($facility)];
88 | } elseif (!in_array($facility, array_values($this->facilities), true)) {
89 | throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given');
90 | }
91 |
92 | $this->facility = $facility;
93 | }
94 |
95 | /**
96 | * {@inheritdoc}
97 | */
98 | protected function getDefaultFormatter(): FormatterInterface
99 | {
100 | return new LineFormatter('%channel%.%level_name%: %message% %context% %extra%');
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/BufferHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Logger;
15 |
16 | /**
17 | * Buffers all records until closing the handler and then pass them as batch.
18 | *
19 | * This is useful for a MailHandler to send only one mail per request instead of
20 | * sending one per log message.
21 | *
22 | * @author Christophe Coevoet
23 | */
24 | class BufferHandler extends AbstractHandler implements ProcessableHandlerInterface
25 | {
26 | use ProcessableHandlerTrait;
27 |
28 | protected $handler;
29 | protected $bufferSize = 0;
30 | protected $bufferLimit;
31 | protected $flushOnOverflow;
32 | protected $buffer = array();
33 | protected $initialized = false;
34 |
35 | /**
36 | * @param HandlerInterface $handler Handler.
37 | * @param int $bufferLimit How many entries should be buffered at most, beyond that the oldest items are removed from the buffer.
38 | * @param int $level The minimum logging level at which this handler will be triggered
39 | * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
40 | * @param Boolean $flushOnOverflow If true, the buffer is flushed when the max size has been reached, by default oldest entries are discarded
41 | */
42 | public function __construct(HandlerInterface $handler, $bufferLimit = 0, $level = Logger::DEBUG, $bubble = true, $flushOnOverflow = false)
43 | {
44 | parent::__construct($level, $bubble);
45 | $this->handler = $handler;
46 | $this->bufferLimit = (int) $bufferLimit;
47 | $this->flushOnOverflow = $flushOnOverflow;
48 | }
49 |
50 | /**
51 | * {@inheritdoc}
52 | */
53 | public function handle(array $record): bool
54 | {
55 | if ($record['level'] < $this->level) {
56 | return false;
57 | }
58 |
59 | if (!$this->initialized) {
60 | // __destructor() doesn't get called on Fatal errors
61 | register_shutdown_function(array($this, 'close'));
62 | $this->initialized = true;
63 | }
64 |
65 | if ($this->bufferLimit > 0 && $this->bufferSize === $this->bufferLimit) {
66 | if ($this->flushOnOverflow) {
67 | $this->flush();
68 | } else {
69 | array_shift($this->buffer);
70 | $this->bufferSize--;
71 | }
72 | }
73 |
74 | if ($this->processors) {
75 | $record = $this->processRecord($record);
76 | }
77 |
78 | $this->buffer[] = $record;
79 | $this->bufferSize++;
80 |
81 | return false === $this->bubble;
82 | }
83 |
84 | public function flush()
85 | {
86 | if ($this->bufferSize === 0) {
87 | return;
88 | }
89 |
90 | $this->handler->handleBatch($this->buffer);
91 | $this->clear();
92 | }
93 |
94 | public function __destruct()
95 | {
96 | // suppress the parent behavior since we already have register_shutdown_function()
97 | // to call close(), and the reference contained there will prevent this from being
98 | // GC'd until the end of the request
99 | }
100 |
101 | /**
102 | * {@inheritdoc}
103 | */
104 | public function close()
105 | {
106 | $this->flush();
107 | }
108 |
109 | /**
110 | * Clears the buffer without flushing any messages down to the wrapped handler.
111 | */
112 | public function clear()
113 | {
114 | $this->bufferSize = 0;
115 | $this->buffer = array();
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/CouchDBHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Formatter\FormatterInterface;
15 | use Monolog\Formatter\JsonFormatter;
16 | use Monolog\Logger;
17 |
18 | /**
19 | * CouchDB handler
20 | *
21 | * @author Markus Bachmann
22 | */
23 | class CouchDBHandler extends AbstractProcessingHandler
24 | {
25 | private $options;
26 |
27 | public function __construct(array $options = array(), $level = Logger::DEBUG, $bubble = true)
28 | {
29 | $this->options = array_merge(array(
30 | 'host' => 'localhost',
31 | 'port' => 5984,
32 | 'dbname' => 'logger',
33 | 'username' => null,
34 | 'password' => null,
35 | ), $options);
36 |
37 | parent::__construct($level, $bubble);
38 | }
39 |
40 | /**
41 | * {@inheritDoc}
42 | */
43 | protected function write(array $record)
44 | {
45 | $basicAuth = null;
46 | if ($this->options['username']) {
47 | $basicAuth = sprintf('%s:%s@', $this->options['username'], $this->options['password']);
48 | }
49 |
50 | $url = 'http://'.$basicAuth.$this->options['host'].':'.$this->options['port'].'/'.$this->options['dbname'];
51 | $context = stream_context_create(array(
52 | 'http' => array(
53 | 'method' => 'POST',
54 | 'content' => $record['formatted'],
55 | 'ignore_errors' => true,
56 | 'max_redirects' => 0,
57 | 'header' => 'Content-type: application/json',
58 | ),
59 | ));
60 |
61 | if (false === @file_get_contents($url, null, $context)) {
62 | throw new \RuntimeException(sprintf('Could not connect to %s', $url));
63 | }
64 | }
65 |
66 | /**
67 | * {@inheritDoc}
68 | */
69 | protected function getDefaultFormatter(): FormatterInterface
70 | {
71 | return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/Curl/Util.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler\Curl;
13 |
14 | class Util
15 | {
16 | private static $retriableErrorCodes = array(
17 | CURLE_COULDNT_RESOLVE_HOST,
18 | CURLE_COULDNT_CONNECT,
19 | CURLE_HTTP_NOT_FOUND,
20 | CURLE_READ_ERROR,
21 | CURLE_OPERATION_TIMEOUTED,
22 | CURLE_HTTP_POST_ERROR,
23 | CURLE_SSL_CONNECT_ERROR,
24 | );
25 |
26 | /**
27 | * Executes a CURL request with optional retries and exception on failure
28 | *
29 | * @param resource $ch curl handler
30 | * @throws \RuntimeException
31 | */
32 | public static function execute($ch, $retries = 5, $closeAfterDone = true)
33 | {
34 | while ($retries--) {
35 | if (curl_exec($ch) === false) {
36 | $curlErrno = curl_errno($ch);
37 |
38 | if (false === in_array($curlErrno, self::$retriableErrorCodes, true) || !$retries) {
39 | $curlError = curl_error($ch);
40 |
41 | if ($closeAfterDone) {
42 | curl_close($ch);
43 | }
44 |
45 | throw new \RuntimeException(sprintf('Curl error (code %s): %s', $curlErrno, $curlError));
46 | }
47 |
48 | continue;
49 | }
50 |
51 | if ($closeAfterDone) {
52 | curl_close($ch);
53 | }
54 | break;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/DoctrineCouchDBHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Logger;
15 | use Monolog\Formatter\NormalizerFormatter;
16 | use Monolog\Formatter\FormatterInterface;
17 | use Doctrine\CouchDB\CouchDBClient;
18 |
19 | /**
20 | * CouchDB handler for Doctrine CouchDB ODM
21 | *
22 | * @author Markus Bachmann
23 | */
24 | class DoctrineCouchDBHandler extends AbstractProcessingHandler
25 | {
26 | private $client;
27 |
28 | public function __construct(CouchDBClient $client, $level = Logger::DEBUG, $bubble = true)
29 | {
30 | $this->client = $client;
31 | parent::__construct($level, $bubble);
32 | }
33 |
34 | /**
35 | * {@inheritDoc}
36 | */
37 | protected function write(array $record)
38 | {
39 | $this->client->postDocument($record['formatted']);
40 | }
41 |
42 | protected function getDefaultFormatter(): FormatterInterface
43 | {
44 | return new NormalizerFormatter;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/DynamoDbHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Aws\Common\Aws;
15 | use Aws\DynamoDb\DynamoDbClient;
16 | use Monolog\Formatter\FormatterInterface;
17 | use Monolog\Formatter\ScalarFormatter;
18 | use Monolog\Logger;
19 |
20 | /**
21 | * Amazon DynamoDB handler (http://aws.amazon.com/dynamodb/)
22 | *
23 | * @link https://github.com/aws/aws-sdk-php/
24 | * @author Andrew Lawson
25 | */
26 | class DynamoDbHandler extends AbstractProcessingHandler
27 | {
28 | const DATE_FORMAT = 'Y-m-d\TH:i:s.uO';
29 |
30 | /**
31 | * @var DynamoDbClient
32 | */
33 | protected $client;
34 |
35 | /**
36 | * @var string
37 | */
38 | protected $table;
39 |
40 | /**
41 | * @param DynamoDbClient $client
42 | * @param string $table
43 | * @param int $level
44 | * @param bool $bubble
45 | */
46 | public function __construct(DynamoDbClient $client, $table, $level = Logger::DEBUG, $bubble = true)
47 | {
48 | if (!defined('Aws\Common\Aws::VERSION') || version_compare('3.0', Aws::VERSION, '<=')) {
49 | throw new \RuntimeException('The DynamoDbHandler is only known to work with the AWS SDK 2.x releases');
50 | }
51 |
52 | $this->client = $client;
53 | $this->table = $table;
54 |
55 | parent::__construct($level, $bubble);
56 | }
57 |
58 | /**
59 | * {@inheritdoc}
60 | */
61 | protected function write(array $record)
62 | {
63 | $filtered = $this->filterEmptyFields($record['formatted']);
64 | $formatted = $this->client->formatAttributes($filtered);
65 |
66 | $this->client->putItem(array(
67 | 'TableName' => $this->table,
68 | 'Item' => $formatted,
69 | ));
70 | }
71 |
72 | /**
73 | * @param array $record
74 | * @return array
75 | */
76 | protected function filterEmptyFields(array $record)
77 | {
78 | return array_filter($record, function ($value) {
79 | return !empty($value) || false === $value || 0 === $value;
80 | });
81 | }
82 |
83 | /**
84 | * {@inheritdoc}
85 | */
86 | protected function getDefaultFormatter(): FormatterInterface
87 | {
88 | return new ScalarFormatter(self::DATE_FORMAT);
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/ErrorLogHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Formatter\LineFormatter;
15 | use Monolog\Formatter\FormatterInterface;
16 | use Monolog\Logger;
17 |
18 | /**
19 | * Stores to PHP error_log() handler.
20 | *
21 | * @author Elan Ruusamäe
22 | */
23 | class ErrorLogHandler extends AbstractProcessingHandler
24 | {
25 | const OPERATING_SYSTEM = 0;
26 | const SAPI = 4;
27 |
28 | protected $messageType;
29 | protected $expandNewlines;
30 |
31 | /**
32 | * @param int $messageType Says where the error should go.
33 | * @param int $level The minimum logging level at which this handler will be triggered
34 | * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
35 | * @param Boolean $expandNewlines If set to true, newlines in the message will be expanded to be take multiple log entries
36 | */
37 | public function __construct($messageType = self::OPERATING_SYSTEM, $level = Logger::DEBUG, $bubble = true, $expandNewlines = false)
38 | {
39 | parent::__construct($level, $bubble);
40 |
41 | if (false === in_array($messageType, self::getAvailableTypes())) {
42 | $message = sprintf('The given message type "%s" is not supported', print_r($messageType, true));
43 | throw new \InvalidArgumentException($message);
44 | }
45 |
46 | $this->messageType = $messageType;
47 | $this->expandNewlines = $expandNewlines;
48 | }
49 |
50 | /**
51 | * @return array With all available types
52 | */
53 | public static function getAvailableTypes()
54 | {
55 | return array(
56 | self::OPERATING_SYSTEM,
57 | self::SAPI,
58 | );
59 | }
60 |
61 | /**
62 | * {@inheritDoc}
63 | */
64 | protected function getDefaultFormatter(): FormatterInterface
65 | {
66 | return new LineFormatter('[%datetime%] %channel%.%level_name%: %message% %context% %extra%');
67 | }
68 |
69 | /**
70 | * {@inheritdoc}
71 | */
72 | protected function write(array $record)
73 | {
74 | if ($this->expandNewlines) {
75 | $lines = preg_split('{[\r\n]+}', (string) $record['formatted']);
76 | foreach ($lines as $line) {
77 | error_log($line, $this->messageType);
78 | }
79 | } else {
80 | error_log((string) $record['formatted'], $this->messageType);
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler\FingersCrossed;
13 |
14 | /**
15 | * Interface for activation strategies for the FingersCrossedHandler.
16 | *
17 | * @author Johannes M. Schmitt
18 | */
19 | interface ActivationStrategyInterface
20 | {
21 | /**
22 | * Returns whether the given record activates the handler.
23 | *
24 | * @param array $record
25 | * @return Boolean
26 | */
27 | public function isHandlerActivated(array $record);
28 | }
29 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler\FingersCrossed;
13 |
14 | use Monolog\Logger;
15 |
16 | /**
17 | * Channel and Error level based monolog activation strategy. Allows to trigger activation
18 | * based on level per channel. e.g. trigger activation on level 'ERROR' by default, except
19 | * for records of the 'sql' channel; those should trigger activation on level 'WARN'.
20 | *
21 | * Example:
22 | *
23 | *
24 | * $activationStrategy = new ChannelLevelActivationStrategy(
25 | * Logger::CRITICAL,
26 | * array(
27 | * 'request' => Logger::ALERT,
28 | * 'sensitive' => Logger::ERROR,
29 | * )
30 | * );
31 | * $handler = new FingersCrossedHandler(new StreamHandler('php://stderr'), $activationStrategy);
32 | *
33 | *
34 | * @author Mike Meessen
35 | */
36 | class ChannelLevelActivationStrategy implements ActivationStrategyInterface
37 | {
38 | private $defaultActionLevel;
39 | private $channelToActionLevel;
40 |
41 | /**
42 | * @param int $defaultActionLevel The default action level to be used if the record's category doesn't match any
43 | * @param array $channelToActionLevel An array that maps channel names to action levels.
44 | */
45 | public function __construct($defaultActionLevel, $channelToActionLevel = array())
46 | {
47 | $this->defaultActionLevel = Logger::toMonologLevel($defaultActionLevel);
48 | $this->channelToActionLevel = array_map('Monolog\Logger::toMonologLevel', $channelToActionLevel);
49 | }
50 |
51 | public function isHandlerActivated(array $record)
52 | {
53 | if (isset($this->channelToActionLevel[$record['channel']])) {
54 | return $record['level'] >= $this->channelToActionLevel[$record['channel']];
55 | }
56 |
57 | return $record['level'] >= $this->defaultActionLevel;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler\FingersCrossed;
13 |
14 | use Monolog\Logger;
15 |
16 | /**
17 | * Error level based activation strategy.
18 | *
19 | * @author Johannes M. Schmitt
20 | */
21 | class ErrorLevelActivationStrategy implements ActivationStrategyInterface
22 | {
23 | private $actionLevel;
24 |
25 | public function __construct($actionLevel)
26 | {
27 | $this->actionLevel = Logger::toMonologLevel($actionLevel);
28 | }
29 |
30 | public function isHandlerActivated(array $record)
31 | {
32 | return $record['level'] >= $this->actionLevel;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/FlowdockHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Logger;
15 | use Monolog\Formatter\FlowdockFormatter;
16 | use Monolog\Formatter\FormatterInterface;
17 |
18 | /**
19 | * Sends notifications through the Flowdock push API
20 | *
21 | * This must be configured with a FlowdockFormatter instance via setFormatter()
22 | *
23 | * Notes:
24 | * API token - Flowdock API token
25 | *
26 | * @author Dominik Liebler
27 | * @see https://www.flowdock.com/api/push
28 | */
29 | class FlowdockHandler extends SocketHandler
30 | {
31 | /**
32 | * @var string
33 | */
34 | protected $apiToken;
35 |
36 | /**
37 | * @param string $apiToken
38 | * @param bool|int $level The minimum logging level at which this handler will be triggered
39 | * @param bool $bubble Whether the messages that are handled can bubble up the stack or not
40 | *
41 | * @throws MissingExtensionException if OpenSSL is missing
42 | */
43 | public function __construct($apiToken, $level = Logger::DEBUG, $bubble = true)
44 | {
45 | if (!extension_loaded('openssl')) {
46 | throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FlowdockHandler');
47 | }
48 |
49 | parent::__construct('ssl://api.flowdock.com:443', $level, $bubble);
50 | $this->apiToken = $apiToken;
51 | }
52 |
53 | /**
54 | * {@inheritdoc}
55 | */
56 | public function setFormatter(FormatterInterface $formatter): HandlerInterface
57 | {
58 | if (!$formatter instanceof FlowdockFormatter) {
59 | throw new \InvalidArgumentException('The FlowdockHandler requires an instance of Monolog\Formatter\FlowdockFormatter to function correctly');
60 | }
61 |
62 | return parent::setFormatter($formatter);
63 | }
64 |
65 | /**
66 | * Gets the default formatter.
67 | *
68 | * @return FormatterInterface
69 | */
70 | protected function getDefaultFormatter(): FormatterInterface
71 | {
72 | throw new \InvalidArgumentException('The FlowdockHandler must be configured (via setFormatter) with an instance of Monolog\Formatter\FlowdockFormatter to function correctly');
73 | }
74 |
75 | /**
76 | * {@inheritdoc}
77 | *
78 | * @param array $record
79 | */
80 | protected function write(array $record)
81 | {
82 | parent::write($record);
83 |
84 | $this->closeSocket();
85 | }
86 |
87 | /**
88 | * {@inheritdoc}
89 | *
90 | * @param array $record
91 | * @return string
92 | */
93 | protected function generateDataStream($record)
94 | {
95 | $content = $this->buildContent($record);
96 |
97 | return $this->buildHeader($content) . $content;
98 | }
99 |
100 | /**
101 | * Builds the body of API call
102 | *
103 | * @param array $record
104 | * @return string
105 | */
106 | private function buildContent($record)
107 | {
108 | return json_encode($record['formatted']['flowdock']);
109 | }
110 |
111 | /**
112 | * Builds the header of the API Call
113 | *
114 | * @param string $content
115 | * @return string
116 | */
117 | private function buildHeader($content)
118 | {
119 | $header = "POST /v1/messages/team_inbox/" . $this->apiToken . " HTTP/1.1\r\n";
120 | $header .= "Host: api.flowdock.com\r\n";
121 | $header .= "Content-Type: application/json\r\n";
122 | $header .= "Content-Length: " . strlen($content) . "\r\n";
123 | $header .= "\r\n";
124 |
125 | return $header;
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/FormattableHandlerInterface.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Formatter\FormatterInterface;
15 |
16 | /**
17 | * Interface to describe loggers that have a formatter
18 | *
19 | * @author Jordi Boggiano
20 | */
21 | interface FormattableHandlerInterface
22 | {
23 | /**
24 | * Sets the formatter.
25 | *
26 | * @param FormatterInterface $formatter
27 | * @return HandlerInterface self
28 | */
29 | public function setFormatter(FormatterInterface $formatter): HandlerInterface;
30 |
31 | /**
32 | * Gets the formatter.
33 | *
34 | * @return FormatterInterface
35 | */
36 | public function getFormatter(): FormatterInterface;
37 | }
38 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/FormattableHandlerTrait.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Formatter\FormatterInterface;
15 | use Monolog\Formatter\LineFormatter;
16 |
17 | /**
18 | * Helper trait for implementing FormattableInterface
19 | *
20 | * @author Jordi Boggiano
21 | */
22 | trait FormattableHandlerTrait
23 | {
24 | /**
25 | * @var FormatterInterface
26 | */
27 | protected $formatter;
28 |
29 | /**
30 | * {@inheritdoc}
31 | */
32 | public function setFormatter(FormatterInterface $formatter): HandlerInterface
33 | {
34 | $this->formatter = $formatter;
35 |
36 | return $this;
37 | }
38 |
39 | /**
40 | * {@inheritdoc}
41 | */
42 | public function getFormatter(): FormatterInterface
43 | {
44 | if (!$this->formatter) {
45 | $this->formatter = $this->getDefaultFormatter();
46 | }
47 |
48 | return $this->formatter;
49 | }
50 |
51 | /**
52 | * Gets the default formatter.
53 | *
54 | * @return FormatterInterface
55 | */
56 | protected function getDefaultFormatter(): FormatterInterface
57 | {
58 | return new LineFormatter();
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/GelfHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Gelf\IMessagePublisher;
15 | use Gelf\PublisherInterface;
16 | use Gelf\Publisher;
17 | use InvalidArgumentException;
18 | use Monolog\Logger;
19 | use Monolog\Formatter\GelfMessageFormatter;
20 | use Monolog\Formatter\FormatterInterface;
21 |
22 | /**
23 | * Handler to send messages to a Graylog2 (http://www.graylog2.org) server
24 | *
25 | * @author Matt Lehner
26 | * @author Benjamin Zikarsky
27 | */
28 | class GelfHandler extends AbstractProcessingHandler
29 | {
30 | /**
31 | * @var Publisher the publisher object that sends the message to the server
32 | */
33 | protected $publisher;
34 |
35 | /**
36 | * @param PublisherInterface|IMessagePublisher|Publisher $publisher a publisher object
37 | * @param int $level The minimum logging level at which this handler will be triggered
38 | * @param bool $bubble Whether the messages that are handled can bubble up the stack or not
39 | */
40 | public function __construct($publisher, $level = Logger::DEBUG, $bubble = true)
41 | {
42 | parent::__construct($level, $bubble);
43 |
44 | if (!$publisher instanceof Publisher && !$publisher instanceof IMessagePublisher && !$publisher instanceof PublisherInterface) {
45 | throw new InvalidArgumentException('Invalid publisher, expected a Gelf\Publisher, Gelf\IMessagePublisher or Gelf\PublisherInterface instance');
46 | }
47 |
48 | $this->publisher = $publisher;
49 | }
50 |
51 | /**
52 | * {@inheritdoc}
53 | */
54 | public function close()
55 | {
56 | $this->publisher = null;
57 | }
58 |
59 | /**
60 | * {@inheritdoc}
61 | */
62 | protected function write(array $record)
63 | {
64 | $this->publisher->publish($record['formatted']);
65 | }
66 |
67 | /**
68 | * {@inheritDoc}
69 | */
70 | protected function getDefaultFormatter(): FormatterInterface
71 | {
72 | return new GelfMessageFormatter();
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/GroupHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Formatter\FormatterInterface;
15 |
16 | /**
17 | * Forwards records to multiple handlers
18 | *
19 | * @author Lenar Lõhmus
20 | */
21 | class GroupHandler extends Handler implements ProcessableHandlerInterface
22 | {
23 | use ProcessableHandlerTrait;
24 |
25 | protected $handlers;
26 |
27 | /**
28 | * @param array $handlers Array of Handlers.
29 | * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
30 | */
31 | public function __construct(array $handlers, $bubble = true)
32 | {
33 | foreach ($handlers as $handler) {
34 | if (!$handler instanceof HandlerInterface) {
35 | throw new \InvalidArgumentException('The first argument of the GroupHandler must be an array of HandlerInterface instances.');
36 | }
37 | }
38 |
39 | $this->handlers = $handlers;
40 | $this->bubble = $bubble;
41 | }
42 |
43 | /**
44 | * {@inheritdoc}
45 | */
46 | public function isHandling(array $record): bool
47 | {
48 | foreach ($this->handlers as $handler) {
49 | if ($handler->isHandling($record)) {
50 | return true;
51 | }
52 | }
53 |
54 | return false;
55 | }
56 |
57 | /**
58 | * {@inheritdoc}
59 | */
60 | public function handle(array $record): bool
61 | {
62 | if ($this->processors) {
63 | $record = $this->processRecord($record);
64 | }
65 |
66 | foreach ($this->handlers as $handler) {
67 | $handler->handle($record);
68 | }
69 |
70 | return false === $this->bubble;
71 | }
72 |
73 | /**
74 | * {@inheritdoc}
75 | */
76 | public function handleBatch(array $records)
77 | {
78 | foreach ($this->handlers as $handler) {
79 | $handler->handleBatch($records);
80 | }
81 | }
82 |
83 | /**
84 | * {@inheritdoc}
85 | */
86 | public function setFormatter(FormatterInterface $formatter)
87 | {
88 | foreach ($this->handlers as $handler) {
89 | $handler->setFormatter($formatter);
90 | }
91 |
92 | return $this;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/Handler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | /**
15 | * Base Handler class providing basic close() support as well as handleBatch
16 | *
17 | * @author Jordi Boggiano
18 | */
19 | abstract class Handler implements HandlerInterface
20 | {
21 | /**
22 | * {@inheritdoc}
23 | */
24 | public function handleBatch(array $records)
25 | {
26 | foreach ($records as $record) {
27 | $this->handle($record);
28 | }
29 | }
30 |
31 | /**
32 | * {@inheritdoc}
33 | */
34 | public function close()
35 | {
36 | }
37 |
38 | public function __destruct()
39 | {
40 | try {
41 | $this->close();
42 | } catch (\Exception $e) {
43 | // do nothing
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/HandlerInterface.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | /**
15 | * Interface that all Monolog Handlers must implement
16 | *
17 | * @author Jordi Boggiano
18 | */
19 | interface HandlerInterface
20 | {
21 | /**
22 | * Checks whether the given record will be handled by this handler.
23 | *
24 | * This is mostly done for performance reasons, to avoid calling processors for nothing.
25 | *
26 | * Handlers should still check the record levels within handle(), returning false in isHandling()
27 | * is no guarantee that handle() will not be called, and isHandling() might not be called
28 | * for a given record.
29 | *
30 | * @param array $record Partial log record containing only a level key
31 | *
32 | * @return Boolean
33 | */
34 | public function isHandling(array $record): bool;
35 |
36 | /**
37 | * Handles a record.
38 | *
39 | * All records may be passed to this method, and the handler should discard
40 | * those that it does not want to handle.
41 | *
42 | * The return value of this function controls the bubbling process of the handler stack.
43 | * Unless the bubbling is interrupted (by returning true), the Logger class will keep on
44 | * calling further handlers in the stack with a given log record.
45 | *
46 | * @param array $record The record to handle
47 | * @return Boolean true means that this handler handled the record, and that bubbling is not permitted.
48 | * false means the record was either not processed or that this handler allows bubbling.
49 | */
50 | public function handle(array $record): bool;
51 |
52 | /**
53 | * Handles a set of records at once.
54 | *
55 | * @param array $records The records to handle (an array of record arrays)
56 | */
57 | public function handleBatch(array $records);
58 |
59 | /**
60 | * Closes the handler.
61 | *
62 | * This will be called automatically when the object is destroyed if you extend Monolog\Handler\Handler
63 | *
64 | * Implementations have to be indempotent (i.e. it should be possible to call close several times without breakage)
65 | * and ideally handlers should be able to reopen themselves on handle() after they have been closed.
66 | */
67 | public function close();
68 | }
69 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/HandlerWrapper.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Formatter\FormatterInterface;
15 |
16 | /**
17 | * This simple wrapper class can be used to extend handlers functionality.
18 | *
19 | * Example: A filtering handle. Inherit from this class, override isHandling() like this
20 | *
21 | * public function isHandling(array $record)
22 | * {
23 | * if ($record meets certain conditions) {
24 | * return false;
25 | * }
26 | * return $this->handler->isHandling($record);
27 | * }
28 | *
29 | * @author Alexey Karapetov
30 | */
31 | class HandlerWrapper implements HandlerInterface, ProcessableHandlerInterface, FormattableHandlerInterface
32 | {
33 | /**
34 | * @var HandlerInterface
35 | */
36 | private $handler;
37 |
38 | /**
39 | * HandlerWrapper constructor.
40 | * @param HandlerInterface $handler
41 | */
42 | public function __construct(HandlerInterface $handler)
43 | {
44 | $this->handler = $handler;
45 | }
46 |
47 | /**
48 | * {@inheritdoc}
49 | */
50 | public function isHandling(array $record): bool
51 | {
52 | return $this->handler->isHandling($record);
53 | }
54 |
55 | /**
56 | * {@inheritdoc}
57 | */
58 | public function handle(array $record): bool
59 | {
60 | return $this->handler->handle($record);
61 | }
62 |
63 | /**
64 | * {@inheritdoc}
65 | */
66 | public function handleBatch(array $records)
67 | {
68 | return $this->handler->handleBatch($records);
69 | }
70 |
71 | /**
72 | * {@inheritdoc}
73 | */
74 | public function close()
75 | {
76 | return $this->handler->close();
77 | }
78 |
79 | /**
80 | * {@inheritdoc}
81 | */
82 | public function pushProcessor(callable $callback): HandlerInterface
83 | {
84 | if ($this->handler instanceof ProcessableHandlerInterface) {
85 | $this->handler->pushProcessor($callback);
86 |
87 | return $this;
88 | }
89 |
90 | throw new \LogicException('The wrapped handler does not implement ' . ProcessableHandlerInterface::class);
91 | }
92 |
93 | /**
94 | * {@inheritdoc}
95 | */
96 | public function popProcessor(): callable
97 | {
98 | if ($this->handler instanceof ProcessableHandlerInterface) {
99 | return $this->handler->popProcessor();
100 | }
101 |
102 | throw new \LogicException('The wrapped handler does not implement ' . ProcessableHandlerInterface::class);
103 | }
104 |
105 | /**
106 | * {@inheritdoc}
107 | */
108 | public function setFormatter(FormatterInterface $formatter): HandlerInterface
109 | {
110 | if ($this->handler instanceof FormattableHandlerInterface) {
111 | $this->handler->setFormatter($formatter);
112 | }
113 |
114 | throw new \LogicException('The wrapped handler does not implement ' . FormattableHandlerInterface::class);
115 | }
116 |
117 | /**
118 | * {@inheritdoc}
119 | */
120 | public function getFormatter(): FormatterInterface
121 | {
122 | if ($this->handler instanceof FormattableHandlerInterface) {
123 | return $this->handler->getFormatter($formatter);
124 | }
125 |
126 | throw new \LogicException('The wrapped handler does not implement ' . FormattableHandlerInterface::class);
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/IFTTTHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Logger;
15 |
16 | /**
17 | * IFTTTHandler uses cURL to trigger IFTTT Maker actions
18 | *
19 | * Register a secret key and trigger/event name at https://ifttt.com/maker
20 | *
21 | * value1 will be the channel from monolog's Logger constructor,
22 | * value2 will be the level name (ERROR, WARNING, ..)
23 | * value3 will be the log record's message
24 | *
25 | * @author Nehal Patel
26 | */
27 | class IFTTTHandler extends AbstractProcessingHandler
28 | {
29 | private $eventName;
30 | private $secretKey;
31 |
32 | /**
33 | * @param string $eventName The name of the IFTTT Maker event that should be triggered
34 | * @param string $secretKey A valid IFTTT secret key
35 | * @param int $level The minimum logging level at which this handler will be triggered
36 | * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
37 | */
38 | public function __construct($eventName, $secretKey, $level = Logger::ERROR, $bubble = true)
39 | {
40 | $this->eventName = $eventName;
41 | $this->secretKey = $secretKey;
42 |
43 | parent::__construct($level, $bubble);
44 | }
45 |
46 | /**
47 | * {@inheritdoc}
48 | */
49 | public function write(array $record)
50 | {
51 | $postData = array(
52 | "value1" => $record["channel"],
53 | "value2" => $record["level_name"],
54 | "value3" => $record["message"],
55 | );
56 | $postString = json_encode($postData);
57 |
58 | $ch = curl_init();
59 | curl_setopt($ch, CURLOPT_URL, "https://maker.ifttt.com/trigger/" . $this->eventName . "/with/key/" . $this->secretKey);
60 | curl_setopt($ch, CURLOPT_POST, true);
61 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
62 | curl_setopt($ch, CURLOPT_POSTFIELDS, $postString);
63 | curl_setopt($ch, CURLOPT_HTTPHEADER, array(
64 | "Content-Type: application/json",
65 | ));
66 |
67 | Curl\Util::execute($ch);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/LogEntriesHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Logger;
15 |
16 | /**
17 | * @author Robert Kaufmann III
18 | */
19 | class LogEntriesHandler extends SocketHandler
20 | {
21 | /**
22 | * @var string
23 | */
24 | protected $logToken;
25 |
26 | /**
27 | * @param string $token Log token supplied by LogEntries
28 | * @param bool $useSSL Whether or not SSL encryption should be used.
29 | * @param int $level The minimum logging level to trigger this handler
30 | * @param bool $bubble Whether or not messages that are handled should bubble up the stack.
31 | *
32 | * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing
33 | */
34 | public function __construct($token, $useSSL = true, $level = Logger::DEBUG, $bubble = true)
35 | {
36 | if ($useSSL && !extension_loaded('openssl')) {
37 | throw new MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for LogEntriesHandler');
38 | }
39 |
40 | $endpoint = $useSSL ? 'ssl://data.logentries.com:443' : 'data.logentries.com:80';
41 | parent::__construct($endpoint, $level, $bubble);
42 | $this->logToken = $token;
43 | }
44 |
45 | /**
46 | * {@inheritdoc}
47 | *
48 | * @param array $record
49 | * @return string
50 | */
51 | protected function generateDataStream($record)
52 | {
53 | return $this->logToken . ' ' . $record['formatted'];
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/LogglyHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Logger;
15 | use Monolog\Formatter\FormatterInterface;
16 | use Monolog\Formatter\LogglyFormatter;
17 |
18 | /**
19 | * Sends errors to Loggly.
20 | *
21 | * @author Przemek Sobstel
22 | * @author Adam Pancutt
23 | * @author Gregory Barchard
24 | */
25 | class LogglyHandler extends AbstractProcessingHandler
26 | {
27 | const HOST = 'logs-01.loggly.com';
28 | const ENDPOINT_SINGLE = 'inputs';
29 | const ENDPOINT_BATCH = 'bulk';
30 |
31 | protected $token;
32 |
33 | protected $tag = array();
34 |
35 | public function __construct($token, $level = Logger::DEBUG, $bubble = true)
36 | {
37 | if (!extension_loaded('curl')) {
38 | throw new \LogicException('The curl extension is needed to use the LogglyHandler');
39 | }
40 |
41 | $this->token = $token;
42 |
43 | parent::__construct($level, $bubble);
44 | }
45 |
46 | public function setTag($tag)
47 | {
48 | $tag = !empty($tag) ? $tag : array();
49 | $this->tag = is_array($tag) ? $tag : array($tag);
50 | }
51 |
52 | public function addTag($tag)
53 | {
54 | if (!empty($tag)) {
55 | $tag = is_array($tag) ? $tag : array($tag);
56 | $this->tag = array_unique(array_merge($this->tag, $tag));
57 | }
58 | }
59 |
60 | protected function write(array $record)
61 | {
62 | $this->send($record["formatted"], self::ENDPOINT_SINGLE);
63 | }
64 |
65 | public function handleBatch(array $records)
66 | {
67 | $level = $this->level;
68 |
69 | $records = array_filter($records, function ($record) use ($level) {
70 | return ($record['level'] >= $level);
71 | });
72 |
73 | if ($records) {
74 | $this->send($this->getFormatter()->formatBatch($records), self::ENDPOINT_BATCH);
75 | }
76 | }
77 |
78 | protected function send($data, $endpoint)
79 | {
80 | $url = sprintf("https://%s/%s/%s/", self::HOST, $endpoint, $this->token);
81 |
82 | $headers = array('Content-Type: application/json');
83 |
84 | if (!empty($this->tag)) {
85 | $headers[] = 'X-LOGGLY-TAG: '.implode(',', $this->tag);
86 | }
87 |
88 | $ch = curl_init();
89 |
90 | curl_setopt($ch, CURLOPT_URL, $url);
91 | curl_setopt($ch, CURLOPT_POST, true);
92 | curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
93 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
94 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
95 |
96 | Curl\Util::execute($ch);
97 | }
98 |
99 | protected function getDefaultFormatter(): FormatterInterface
100 | {
101 | return new LogglyFormatter();
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/MailHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | /**
15 | * Base class for all mail handlers
16 | *
17 | * @author Gyula Sallai
18 | */
19 | abstract class MailHandler extends AbstractProcessingHandler
20 | {
21 | /**
22 | * {@inheritdoc}
23 | */
24 | public function handleBatch(array $records)
25 | {
26 | $messages = array();
27 |
28 | foreach ($records as $record) {
29 | if ($record['level'] < $this->level) {
30 | continue;
31 | }
32 | $messages[] = $this->processRecord($record);
33 | }
34 |
35 | if (!empty($messages)) {
36 | $this->send((string) $this->getFormatter()->formatBatch($messages), $messages);
37 | }
38 | }
39 |
40 | /**
41 | * Send a mail with the given content
42 | *
43 | * @param string $content formatted email body to be sent
44 | * @param array $records the array of log records that formed this content
45 | */
46 | abstract protected function send($content, array $records);
47 |
48 | /**
49 | * {@inheritdoc}
50 | */
51 | protected function write(array $record)
52 | {
53 | $this->send((string) $record['formatted'], array($record));
54 | }
55 |
56 | protected function getHighestRecord(array $records)
57 | {
58 | $highestRecord = null;
59 | foreach ($records as $record) {
60 | if ($highestRecord === null || $highestRecord['level'] < $record['level']) {
61 | $highestRecord = $record;
62 | }
63 | }
64 |
65 | return $highestRecord;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/MandrillHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Logger;
15 |
16 | /**
17 | * MandrillHandler uses cURL to send the emails to the Mandrill API
18 | *
19 | * @author Adam Nicholson
20 | */
21 | class MandrillHandler extends MailHandler
22 | {
23 | protected $message;
24 | protected $apiKey;
25 |
26 | /**
27 | * @param string $apiKey A valid Mandrill API key
28 | * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced
29 | * @param int $level The minimum logging level at which this handler will be triggered
30 | * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
31 | */
32 | public function __construct($apiKey, $message, $level = Logger::ERROR, $bubble = true)
33 | {
34 | parent::__construct($level, $bubble);
35 |
36 | if (!$message instanceof \Swift_Message && is_callable($message)) {
37 | $message = call_user_func($message);
38 | }
39 | if (!$message instanceof \Swift_Message) {
40 | throw new \InvalidArgumentException('You must provide either a Swift_Message instance or a callable returning it');
41 | }
42 | $this->message = $message;
43 | $this->apiKey = $apiKey;
44 | }
45 |
46 | /**
47 | * {@inheritdoc}
48 | */
49 | protected function send($content, array $records)
50 | {
51 | $message = clone $this->message;
52 | $message->setBody($content);
53 | $message->setDate(time());
54 |
55 | $ch = curl_init();
56 |
57 | curl_setopt($ch, CURLOPT_URL, 'https://mandrillapp.com/api/1.0/messages/send-raw.json');
58 | curl_setopt($ch, CURLOPT_POST, 1);
59 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
60 | curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
61 | 'key' => $this->apiKey,
62 | 'raw_message' => (string) $message,
63 | 'async' => false,
64 | )));
65 |
66 | Curl\Util::execute($ch);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/MissingExtensionException.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | /**
15 | * Exception can be thrown if an extension for an handler is missing
16 | *
17 | * @author Christian Bergau
18 | */
19 | class MissingExtensionException extends \Exception
20 | {
21 | }
22 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/MongoDBHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use MongoDB\Driver\BulkWrite;
15 | use MongoDB\Driver\Manager;
16 | use MongoDB\Client;
17 | use Monolog\Logger;
18 | use Monolog\Formatter\FormatterInterface;
19 | use Monolog\Formatter\NormalizerFormatter;
20 |
21 | /**
22 | * Logs to a MongoDB database.
23 | *
24 | * Usage example:
25 | *
26 | * $log = new \Monolog\Logger('application');
27 | * $client = new \MongoDB\Client('mongodb://localhost:27017');
28 | * $mongodb = new \Monolog\Handler\MongoDBHandler($client, 'logs', 'prod');
29 | * $log->pushHandler($mongodb);
30 | *
31 | * The above examples uses the MongoDB PHP library's client class; however, the
32 | * MongoDB\Driver\Manager class from ext-mongodb is also supported.
33 | */
34 | class MongoDBHandler extends AbstractProcessingHandler
35 | {
36 | private $collection;
37 | private $manager;
38 | private $namespace;
39 |
40 | /**
41 | * Constructor.
42 | *
43 | * @param Client|Manager $mongodb MongoDB library or driver client
44 | * @param string $database Database name
45 | * @param string $collection Collection name
46 | * @param int $level The minimum logging level at which this handler will be triggered
47 | * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
48 | */
49 | public function __construct($mongodb, $database, $collection, $level = Logger::DEBUG, $bubble = true)
50 | {
51 | if (!($mongodb instanceof Client || $mongodb instanceof Manager)) {
52 | throw new \InvalidArgumentException('MongoDB\Client or MongoDB\Driver\Manager instance required');
53 | }
54 |
55 | if ($mongodb instanceof Client) {
56 | $this->collection = $mongodb->selectCollection($database, $collection);
57 | } else {
58 | $this->manager = $mongodb;
59 | $this->namespace = $database . '.' . $collection;
60 | }
61 |
62 | parent::__construct($level, $bubble);
63 | }
64 |
65 | protected function write(array $record)
66 | {
67 | if (isset($this->collection)) {
68 | $this->collection->insertOne($record['formatted']);
69 | }
70 |
71 | if (isset($this->manager, $this->namespace)) {
72 | $bulk = new BulkWrite;
73 | $bulk->insert($record["formatted"]);
74 | $this->manager->executeBulkWrite($this->namespace, $bulk);
75 | }
76 | }
77 |
78 | /**
79 | * {@inheritDoc}
80 | */
81 | protected function getDefaultFormatter(): FormatterInterface
82 | {
83 | return new NormalizerFormatter;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/NullHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Logger;
15 |
16 | /**
17 | * Blackhole
18 | *
19 | * Any record it can handle will be thrown away. This can be used
20 | * to put on top of an existing stack to override it temporarily.
21 | *
22 | * @author Jordi Boggiano
23 | */
24 | class NullHandler extends Handler
25 | {
26 | private $level;
27 |
28 | /**
29 | * @param int $level The minimum logging level at which this handler will be triggered
30 | */
31 | public function __construct(int $level = Logger::DEBUG)
32 | {
33 | $this->level = $level;
34 | }
35 |
36 | /**
37 | * {@inheritdoc}
38 | */
39 | public function isHandling(array $record): bool
40 | {
41 | return $record['level'] >= $this->level;
42 | }
43 |
44 | /**
45 | * {@inheritdoc}
46 | */
47 | public function handle(array $record): bool
48 | {
49 | if ($record['level'] < $this->level) {
50 | return false;
51 | }
52 |
53 | return true;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/ProcessableHandlerInterface.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | /**
15 | * Interface to describe loggers that have processors
16 | *
17 | * @author Jordi Boggiano
18 | */
19 | interface ProcessableHandlerInterface
20 | {
21 | /**
22 | * Adds a processor in the stack.
23 | *
24 | * @param callable $callback
25 | * @return HandlerInterface self
26 | */
27 | public function pushProcessor(callable $callback): HandlerInterface;
28 |
29 | /**
30 | * Removes the processor on top of the stack and returns it.
31 | *
32 | * @throws LogicException In case the processor stack is empty
33 | * @return callable
34 | */
35 | public function popProcessor(): callable;
36 | }
37 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/ProcessableHandlerTrait.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | /**
15 | * Helper trait for implementing ProcessableInterface
16 | *
17 | * @author Jordi Boggiano
18 | */
19 | trait ProcessableHandlerTrait
20 | {
21 | /**
22 | * @var callable[]
23 | */
24 | protected $processors = [];
25 |
26 | /**
27 | * {@inheritdoc}
28 | */
29 | public function pushProcessor(callable $callback): HandlerInterface
30 | {
31 | if (!is_callable($callback)) {
32 | throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given');
33 | }
34 | array_unshift($this->processors, $callback);
35 |
36 | return $this;
37 | }
38 |
39 | /**
40 | * {@inheritdoc}
41 | */
42 | public function popProcessor(): callable
43 | {
44 | if (!$this->processors) {
45 | throw new \LogicException('You tried to pop from an empty processor stack.');
46 | }
47 |
48 | return array_shift($this->processors);
49 | }
50 |
51 | /**
52 | * Processes a record.
53 | *
54 | * @param array $record
55 | * @return array
56 | */
57 | protected function processRecord(array $record)
58 | {
59 | foreach ($this->processors as $processor) {
60 | $record = $processor($record);
61 | }
62 |
63 | return $record;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/PsrHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Logger;
15 | use Psr\Log\LoggerInterface;
16 |
17 | /**
18 | * Proxies log messages to an existing PSR-3 compliant logger.
19 | *
20 | * @author Michael Moussa
21 | */
22 | class PsrHandler extends AbstractHandler
23 | {
24 | /**
25 | * PSR-3 compliant logger
26 | *
27 | * @var LoggerInterface
28 | */
29 | protected $logger;
30 |
31 | /**
32 | * @param LoggerInterface $logger The underlying PSR-3 compliant logger to which messages will be proxied
33 | * @param int $level The minimum logging level at which this handler will be triggered
34 | * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
35 | */
36 | public function __construct(LoggerInterface $logger, $level = Logger::DEBUG, $bubble = true)
37 | {
38 | parent::__construct($level, $bubble);
39 |
40 | $this->logger = $logger;
41 | }
42 |
43 | /**
44 | * {@inheritDoc}
45 | */
46 | public function handle(array $record): bool
47 | {
48 | if (!$this->isHandling($record)) {
49 | return false;
50 | }
51 |
52 | $this->logger->log(strtolower($record['level_name']), $record['message'], $record['context']);
53 |
54 | return false === $this->bubble;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/RedisHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Formatter\LineFormatter;
15 | use Monolog\Formatter\FormatterInterface;
16 | use Monolog\Logger;
17 |
18 | /**
19 | * Logs to a Redis key using rpush
20 | *
21 | * usage example:
22 | *
23 | * $log = new Logger('application');
24 | * $redis = new RedisHandler(new Predis\Client("tcp://localhost:6379"), "logs", "prod");
25 | * $log->pushHandler($redis);
26 | *
27 | * @author Thomas Tourlourat
28 | */
29 | class RedisHandler extends AbstractProcessingHandler
30 | {
31 | private $redisClient;
32 | private $redisKey;
33 | protected $capSize;
34 |
35 | /**
36 | * @param \Predis\Client|\Redis $redis The redis instance
37 | * @param string $key The key name to push records to
38 | * @param int $level The minimum logging level at which this handler will be triggered
39 | * @param bool $bubble Whether the messages that are handled can bubble up the stack or not
40 | * @param int $capSize Number of entries to limit list size to
41 | */
42 | public function __construct($redis, $key, $level = Logger::DEBUG, $bubble = true, $capSize = false)
43 | {
44 | if (!(($redis instanceof \Predis\Client) || ($redis instanceof \Redis))) {
45 | throw new \InvalidArgumentException('Predis\Client or Redis instance required');
46 | }
47 |
48 | $this->redisClient = $redis;
49 | $this->redisKey = $key;
50 | $this->capSize = $capSize;
51 |
52 | parent::__construct($level, $bubble);
53 | }
54 |
55 | /**
56 | * {@inheritDoc}
57 | */
58 | protected function write(array $record)
59 | {
60 | if ($this->capSize) {
61 | $this->writeCapped($record);
62 | } else {
63 | $this->redisClient->rpush($this->redisKey, $record["formatted"]);
64 | }
65 | }
66 |
67 | /**
68 | * Write and cap the collection
69 | * Writes the record to the redis list and caps its
70 | *
71 | * @param array $record associative record array
72 | * @return void
73 | */
74 | protected function writeCapped(array $record)
75 | {
76 | if ($this->redisClient instanceof \Redis) {
77 | $this->redisClient->multi()
78 | ->rpush($this->redisKey, $record["formatted"])
79 | ->ltrim($this->redisKey, -$this->capSize, -1)
80 | ->exec();
81 | } else {
82 | $redisKey = $this->redisKey;
83 | $capSize = $this->capSize;
84 | $this->redisClient->transaction(function ($tx) use ($record, $redisKey, $capSize) {
85 | $tx->rpush($redisKey, $record["formatted"]);
86 | $tx->ltrim($redisKey, -$capSize, -1);
87 | });
88 | }
89 | }
90 |
91 | /**
92 | * {@inheritDoc}
93 | */
94 | protected function getDefaultFormatter(): FormatterInterface
95 | {
96 | return new LineFormatter();
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/RollbarHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use RollbarNotifier;
15 | use Exception;
16 | use Monolog\Logger;
17 |
18 | /**
19 | * Sends errors to Rollbar
20 | *
21 | * If the context data contains a `payload` key, that is used as an array
22 | * of payload options to RollbarNotifier's report_message/report_exception methods.
23 | *
24 | * @author Paul Statezny
25 | */
26 | class RollbarHandler extends AbstractProcessingHandler
27 | {
28 | /**
29 | * Rollbar notifier
30 | *
31 | * @var RollbarNotifier
32 | */
33 | protected $rollbarNotifier;
34 |
35 | /**
36 | * Records whether any log records have been added since the last flush of the rollbar notifier
37 | *
38 | * @var bool
39 | */
40 | private $hasRecords = false;
41 |
42 | /**
43 | * @param RollbarNotifier $rollbarNotifier RollbarNotifier object constructed with valid token
44 | * @param int $level The minimum logging level at which this handler will be triggered
45 | * @param bool $bubble Whether the messages that are handled can bubble up the stack or not
46 | */
47 | public function __construct(RollbarNotifier $rollbarNotifier, $level = Logger::ERROR, $bubble = true)
48 | {
49 | $this->rollbarNotifier = $rollbarNotifier;
50 |
51 | parent::__construct($level, $bubble);
52 | }
53 |
54 | /**
55 | * {@inheritdoc}
56 | */
57 | protected function write(array $record)
58 | {
59 | if (isset($record['context']['exception']) && $record['context']['exception'] instanceof Exception) {
60 | $context = $record['context'];
61 | $exception = $context['exception'];
62 | unset($context['exception']);
63 |
64 | $payload = array();
65 | if (isset($context['payload'])) {
66 | $payload = $context['payload'];
67 | unset($context['payload']);
68 | }
69 |
70 | $this->rollbarNotifier->report_exception($exception, $context, $payload);
71 | } else {
72 | $extraData = array(
73 | 'level' => $record['level'],
74 | 'channel' => $record['channel'],
75 | 'datetime' => $record['datetime']->format('U'),
76 | );
77 |
78 | $context = $record['context'];
79 | $payload = array();
80 | if (isset($context['payload'])) {
81 | $payload = $context['payload'];
82 | unset($context['payload']);
83 | }
84 |
85 | $this->rollbarNotifier->report_message(
86 | $record['message'],
87 | $record['level_name'],
88 | array_merge($record['context'], $record['extra'], $extraData),
89 | $payload
90 | );
91 | }
92 |
93 | $this->hasRecords = true;
94 | }
95 |
96 | /**
97 | * {@inheritdoc}
98 | */
99 | public function close()
100 | {
101 | if ($this->hasRecords) {
102 | $this->rollbarNotifier->flush();
103 | $this->hasRecords = false;
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/SamplingHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | /**
15 | * Sampling handler
16 | *
17 | * A sampled event stream can be useful for logging high frequency events in
18 | * a production environment where you only need an idea of what is happening
19 | * and are not concerned with capturing every occurrence. Since the decision to
20 | * handle or not handle a particular event is determined randomly, the
21 | * resulting sampled log is not guaranteed to contain 1/N of the events that
22 | * occurred in the application, but based on the Law of large numbers, it will
23 | * tend to be close to this ratio with a large number of attempts.
24 | *
25 | * @author Bryan Davis
26 | * @author Kunal Mehta
27 | */
28 | class SamplingHandler extends AbstractHandler implements ProcessableHandlerInterface
29 | {
30 | use ProcessableHandlerTrait;
31 |
32 | /**
33 | * @var callable|HandlerInterface $handler
34 | */
35 | protected $handler;
36 |
37 | /**
38 | * @var int $factor
39 | */
40 | protected $factor;
41 |
42 | /**
43 | * @param callable|HandlerInterface $handler Handler or factory callable($record, $fingersCrossedHandler).
44 | * @param int $factor Sample factor
45 | */
46 | public function __construct($handler, $factor)
47 | {
48 | parent::__construct();
49 | $this->handler = $handler;
50 | $this->factor = $factor;
51 |
52 | if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) {
53 | throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object");
54 | }
55 | }
56 |
57 | public function isHandling(array $record): bool
58 | {
59 | return $this->handler->isHandling($record);
60 | }
61 |
62 | public function handle(array $record): bool
63 | {
64 | if ($this->isHandling($record) && mt_rand(1, $this->factor) === 1) {
65 | // The same logic as in FingersCrossedHandler
66 | if (!$this->handler instanceof HandlerInterface) {
67 | $this->handler = call_user_func($this->handler, $record, $this);
68 | if (!$this->handler instanceof HandlerInterface) {
69 | throw new \RuntimeException("The factory callable should return a HandlerInterface");
70 | }
71 | }
72 |
73 | if ($this->processors) {
74 | $record = $this->processRecord($record);
75 | }
76 |
77 | $this->handler->handle($record);
78 | }
79 |
80 | return false === $this->bubble;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/SwiftMailerHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Logger;
15 | use Monolog\Formatter\LineFormatter;
16 |
17 | /**
18 | * SwiftMailerHandler uses Swift_Mailer to send the emails
19 | *
20 | * @author Gyula Sallai
21 | */
22 | class SwiftMailerHandler extends MailHandler
23 | {
24 | protected $mailer;
25 | private $messageTemplate;
26 |
27 | /**
28 | * @param \Swift_Mailer $mailer The mailer to use
29 | * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced
30 | * @param int $level The minimum logging level at which this handler will be triggered
31 | * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
32 | */
33 | public function __construct(\Swift_Mailer $mailer, $message, $level = Logger::ERROR, $bubble = true)
34 | {
35 | parent::__construct($level, $bubble);
36 |
37 | $this->mailer = $mailer;
38 | $this->messageTemplate = $message;
39 | }
40 |
41 | /**
42 | * {@inheritdoc}
43 | */
44 | protected function send($content, array $records)
45 | {
46 | $this->mailer->send($this->buildMessage($content, $records));
47 | }
48 |
49 | /**
50 | * Creates instance of Swift_Message to be sent
51 | *
52 | * @param string $content formatted email body to be sent
53 | * @param array $records Log records that formed the content
54 | * @return \Swift_Message
55 | */
56 | protected function buildMessage($content, array $records)
57 | {
58 | $message = null;
59 | if ($this->messageTemplate instanceof \Swift_Message) {
60 | $message = clone $this->messageTemplate;
61 | $message->generateId();
62 | } elseif (is_callable($this->messageTemplate)) {
63 | $message = call_user_func($this->messageTemplate, $content, $records);
64 | }
65 |
66 | if (!$message instanceof \Swift_Message) {
67 | throw new \InvalidArgumentException('Could not resolve message as instance of Swift_Message or a callable returning it');
68 | }
69 |
70 | if ($records) {
71 | $subjectFormatter = new LineFormatter($message->getSubject());
72 | $message->setSubject($subjectFormatter->format($this->getHighestRecord($records)));
73 | }
74 |
75 | $message->setBody($content);
76 | $message->setDate(time());
77 |
78 | return $message;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/SyslogHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Logger;
15 |
16 | /**
17 | * Logs to syslog service.
18 | *
19 | * usage example:
20 | *
21 | * $log = new Logger('application');
22 | * $syslog = new SyslogHandler('myfacility', 'local6');
23 | * $formatter = new LineFormatter("%channel%.%level_name%: %message% %extra%");
24 | * $syslog->setFormatter($formatter);
25 | * $log->pushHandler($syslog);
26 | *
27 | * @author Sven Paulus
28 | */
29 | class SyslogHandler extends AbstractSyslogHandler
30 | {
31 | protected $ident;
32 | protected $logopts;
33 |
34 | /**
35 | * @param string $ident
36 | * @param mixed $facility
37 | * @param int $level The minimum logging level at which this handler will be triggered
38 | * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
39 | * @param int $logopts Option flags for the openlog() call, defaults to LOG_PID
40 | */
41 | public function __construct($ident, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true, $logopts = LOG_PID)
42 | {
43 | parent::__construct($facility, $level, $bubble);
44 |
45 | $this->ident = $ident;
46 | $this->logopts = $logopts;
47 | }
48 |
49 | /**
50 | * {@inheritdoc}
51 | */
52 | public function close()
53 | {
54 | closelog();
55 | }
56 |
57 | /**
58 | * {@inheritdoc}
59 | */
60 | protected function write(array $record)
61 | {
62 | if (!openlog($this->ident, $this->logopts, $this->facility)) {
63 | throw new \LogicException('Can\'t open syslog for ident "'.$this->ident.'" and facility "'.$this->facility.'"');
64 | }
65 | syslog($this->logLevels[$record['level']], (string) $record['formatted']);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/SyslogUdp/UdpSocket.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler\SyslogUdp;
13 |
14 | class UdpSocket
15 | {
16 | const DATAGRAM_MAX_LENGTH = 65023;
17 |
18 | protected $ip;
19 | protected $port;
20 | protected $socket;
21 |
22 | public function __construct($ip, $port = 514)
23 | {
24 | $this->ip = $ip;
25 | $this->port = $port;
26 | $this->socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
27 | }
28 |
29 | public function write($line, $header = "")
30 | {
31 | $this->send($this->assembleMessage($line, $header));
32 | }
33 |
34 | public function close()
35 | {
36 | if (is_resource($this->socket)) {
37 | socket_close($this->socket);
38 | $this->socket = null;
39 | }
40 | }
41 |
42 | protected function send($chunk)
43 | {
44 | if (!is_resource($this->socket)) {
45 | throw new \LogicException('The UdpSocket to '.$this->ip.':'.$this->port.' has been closed and can not be written to anymore');
46 | }
47 | socket_sendto($this->socket, $chunk, strlen($chunk), $flags = 0, $this->ip, $this->port);
48 | }
49 |
50 | protected function assembleMessage($line, $header)
51 | {
52 | $chunkSize = self::DATAGRAM_MAX_LENGTH - strlen($header);
53 |
54 | return $header . substr($line, 0, $chunkSize);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/SyslogUdpHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | use Monolog\Logger;
15 | use Monolog\Handler\SyslogUdp\UdpSocket;
16 |
17 | /**
18 | * A Handler for logging to a remote syslogd server.
19 | *
20 | * @author Jesper Skovgaard Nielsen
21 | */
22 | class SyslogUdpHandler extends AbstractSyslogHandler
23 | {
24 | protected $socket;
25 |
26 | /**
27 | * @param string $host
28 | * @param int $port
29 | * @param mixed $facility
30 | * @param int $level The minimum logging level at which this handler will be triggered
31 | * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
32 | */
33 | public function __construct($host, $port = 514, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true)
34 | {
35 | parent::__construct($facility, $level, $bubble);
36 |
37 | $this->socket = new UdpSocket($host, $port ?: 514);
38 | }
39 |
40 | protected function write(array $record)
41 | {
42 | $lines = $this->splitMessageIntoLines($record['formatted']);
43 |
44 | $header = $this->makeCommonSyslogHeader($this->logLevels[$record['level']]);
45 |
46 | foreach ($lines as $line) {
47 | $this->socket->write($line, $header);
48 | }
49 | }
50 |
51 | public function close()
52 | {
53 | $this->socket->close();
54 | }
55 |
56 | private function splitMessageIntoLines($message)
57 | {
58 | if (is_array($message)) {
59 | $message = implode("\n", $message);
60 | }
61 |
62 | return preg_split('/$\R?^/m', $message);
63 | }
64 |
65 | /**
66 | * Make common syslog header (see rfc5424)
67 | */
68 | protected function makeCommonSyslogHeader($severity)
69 | {
70 | $priority = $severity + $this->facility;
71 |
72 | return "<$priority>1 ";
73 | }
74 |
75 | /**
76 | * Inject your own socket, mainly used for testing
77 | */
78 | public function setSocket($socket)
79 | {
80 | $this->socket = $socket;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/WhatFailureGroupHandler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Handler;
13 |
14 | /**
15 | * Forwards records to multiple handlers suppressing failures of each handler
16 | * and continuing through to give every handler a chance to succeed.
17 | *
18 | * @author Craig D'Amelio
19 | */
20 | class WhatFailureGroupHandler extends GroupHandler
21 | {
22 | /**
23 | * {@inheritdoc}
24 | */
25 | public function handle(array $record): bool
26 | {
27 | if ($this->processors) {
28 | foreach ($this->processors as $processor) {
29 | $record = call_user_func($processor, $record);
30 | }
31 | }
32 |
33 | foreach ($this->handlers as $handler) {
34 | try {
35 | $handler->handle($record);
36 | } catch (\Exception $e) {
37 | // What failure?
38 | }
39 | }
40 |
41 | return false === $this->bubble;
42 | }
43 |
44 | /**
45 | * {@inheritdoc}
46 | */
47 | public function handleBatch(array $records)
48 | {
49 | foreach ($this->handlers as $handler) {
50 | try {
51 | $handler->handleBatch($records);
52 | } catch (\Exception $e) {
53 | // What failure?
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Logger/Monolog/Handler/ZendMonitorHandler.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | namespace Monolog\Handler;
12 |
13 | use Monolog\Formatter\FormatterInterface;
14 | use Monolog\Formatter\NormalizerFormatter;
15 | use Monolog\Logger;
16 |
17 | /**
18 | * Handler sending logs to Zend Monitor
19 | *
20 | * @author Christian Bergau
21 | */
22 | class ZendMonitorHandler extends AbstractProcessingHandler
23 | {
24 | /**
25 | * Monolog level / ZendMonitor Custom Event priority map
26 | *
27 | * @var array
28 | */
29 | protected $levelMap = array(
30 | Logger::DEBUG => 1,
31 | Logger::INFO => 2,
32 | Logger::NOTICE => 3,
33 | Logger::WARNING => 4,
34 | Logger::ERROR => 5,
35 | Logger::CRITICAL => 6,
36 | Logger::ALERT => 7,
37 | Logger::EMERGENCY => 0,
38 | );
39 |
40 | /**
41 | * Construct
42 | *
43 | * @param int $level
44 | * @param bool $bubble
45 | * @throws MissingExtensionException
46 | */
47 | public function __construct($level = Logger::DEBUG, $bubble = true)
48 | {
49 | if (!function_exists('zend_monitor_custom_event')) {
50 | throw new MissingExtensionException('You must have Zend Server installed in order to use this handler');
51 | }
52 | parent::__construct($level, $bubble);
53 | }
54 |
55 | /**
56 | * {@inheritdoc}
57 | */
58 | protected function write(array $record)
59 | {
60 | $this->writeZendMonitorCustomEvent(
61 | $this->levelMap[$record['level']],
62 | $record['message'],
63 | $record['formatted']
64 | );
65 | }
66 |
67 | /**
68 | * Write a record to Zend Monitor
69 | *
70 | * @param int $level
71 | * @param string $message
72 | * @param array $formatted
73 | */
74 | protected function writeZendMonitorCustomEvent($level, $message, $formatted)
75 | {
76 | zend_monitor_custom_event($level, $message, $formatted);
77 | }
78 |
79 | /**
80 | * {@inheritdoc}
81 | */
82 | public function getDefaultFormatter(): FormatterInterface
83 | {
84 | return new NormalizerFormatter();
85 | }
86 |
87 | /**
88 | * Get the level map
89 | *
90 | * @return array
91 | */
92 | public function getLevelMap()
93 | {
94 | return $this->levelMap;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/Logger/Monolog/Processor/GitProcessor.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Processor;
13 |
14 | use Monolog\Logger;
15 |
16 | /**
17 | * Injects Git branch and Git commit SHA in all records
18 | *
19 | * @author Nick Otter
20 | * @author Jordi Boggiano
21 | */
22 | class GitProcessor
23 | {
24 | private $level;
25 | private static $cache;
26 |
27 | public function __construct($level = Logger::DEBUG)
28 | {
29 | $this->level = Logger::toMonologLevel($level);
30 | }
31 |
32 | /**
33 | * @param array $record
34 | * @return array
35 | */
36 | public function __invoke(array $record)
37 | {
38 | // return if the level is not high enough
39 | if ($record['level'] < $this->level) {
40 | return $record;
41 | }
42 |
43 | $record['extra']['git'] = self::getGitInfo();
44 |
45 | return $record;
46 | }
47 |
48 | private static function getGitInfo()
49 | {
50 | if (self::$cache) {
51 | return self::$cache;
52 | }
53 |
54 | $branches = `git branch -v --no-abbrev`;
55 | if (preg_match('{^\* (.+?)\s+([a-f0-9]{40})(?:\s|$)}m', $branches, $matches)) {
56 | return self::$cache = array(
57 | 'branch' => $matches[1],
58 | 'commit' => $matches[2],
59 | );
60 | }
61 |
62 | return self::$cache = array();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Logger/Monolog/Processor/IntrospectionProcessor.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Processor;
13 |
14 | use Monolog\Logger;
15 |
16 | /**
17 | * Injects line/file:class/function where the log message came from
18 | *
19 | * Warning: This only works if the handler processes the logs directly.
20 | * If you put the processor on a handler that is behind a FingersCrossedHandler
21 | * for example, the processor will only be called once the trigger level is reached,
22 | * and all the log records will have the same file/line/.. data from the call that
23 | * triggered the FingersCrossedHandler.
24 | *
25 | * @author Jordi Boggiano
26 | */
27 | class IntrospectionProcessor
28 | {
29 | private $level;
30 |
31 | private $skipClassesPartials;
32 |
33 | private $skipStackFramesCount;
34 |
35 | private $skipFunctions = array(
36 | 'call_user_func',
37 | 'call_user_func_array',
38 | );
39 |
40 | public function __construct($level = Logger::DEBUG, array $skipClassesPartials = array(), $skipStackFramesCount = 0)
41 | {
42 | $this->level = Logger::toMonologLevel($level);
43 | $this->skipClassesPartials = array_merge(array('Monolog\\'), $skipClassesPartials);
44 | $this->skipStackFramesCount = $skipStackFramesCount;
45 | }
46 |
47 | /**
48 | * @param array $record
49 | * @return array
50 | */
51 | public function __invoke(array $record)
52 | {
53 | // return if the level is not high enough
54 | if ($record['level'] < $this->level) {
55 | return $record;
56 | }
57 |
58 | $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
59 |
60 | // skip first since it's always the current method
61 | array_shift($trace);
62 | // the call_user_func call is also skipped
63 | array_shift($trace);
64 |
65 | $i = 0;
66 |
67 | while ($this->isTraceClassOrSkippedFunction($trace, $i)) {
68 | if (isset($trace[$i]['class'])) {
69 | foreach ($this->skipClassesPartials as $part) {
70 | if (strpos($trace[$i]['class'], $part) !== false) {
71 | $i++;
72 | continue 2;
73 | }
74 | }
75 | } elseif (in_array($trace[$i]['function'], $this->skipFunctions)) {
76 | $i++;
77 | continue;
78 | }
79 |
80 | break;
81 | }
82 |
83 | $i += $this->skipStackFramesCount;
84 |
85 | // we should have the call source now
86 | $record['extra'] = array_merge(
87 | $record['extra'],
88 | array(
89 | 'file' => isset($trace[$i - 1]['file']) ? $trace[$i - 1]['file'] : null,
90 | 'line' => isset($trace[$i - 1]['line']) ? $trace[$i - 1]['line'] : null,
91 | 'class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : null,
92 | 'function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : null,
93 | )
94 | );
95 |
96 | return $record;
97 | }
98 |
99 | private function isTraceClassOrSkippedFunction(array $trace, $index)
100 | {
101 | if (!isset($trace[$index])) {
102 | return false;
103 | }
104 |
105 | return isset($trace[$index]['class']) || in_array($trace[$index]['function'], $this->skipFunctions);
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/Logger/Monolog/Processor/MemoryPeakUsageProcessor.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Processor;
13 |
14 | /**
15 | * Injects memory_get_peak_usage in all records
16 | *
17 | * @see Monolog\Processor\MemoryProcessor::__construct() for options
18 | * @author Rob Jensen
19 | */
20 | class MemoryPeakUsageProcessor extends MemoryProcessor
21 | {
22 | /**
23 | * @param array $record
24 | * @return array
25 | */
26 | public function __invoke(array $record)
27 | {
28 | $bytes = memory_get_peak_usage($this->realUsage);
29 | $formatted = $this->formatBytes($bytes);
30 |
31 | $record['extra']['memory_peak_usage'] = $formatted;
32 |
33 | return $record;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Logger/Monolog/Processor/MemoryProcessor.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Processor;
13 |
14 | /**
15 | * Some methods that are common for all memory processors
16 | *
17 | * @author Rob Jensen
18 | */
19 | abstract class MemoryProcessor
20 | {
21 | /**
22 | * @var bool If true, get the real size of memory allocated from system. Else, only the memory used by emalloc() is reported.
23 | */
24 | protected $realUsage;
25 |
26 | /**
27 | * @var bool If true, then format memory size to human readable string (MB, KB, B depending on size)
28 | */
29 | protected $useFormatting;
30 |
31 | /**
32 | * @param bool $realUsage Set this to true to get the real size of memory allocated from system.
33 | * @param bool $useFormatting If true, then format memory size to human readable string (MB, KB, B depending on size)
34 | */
35 | public function __construct($realUsage = true, $useFormatting = true)
36 | {
37 | $this->realUsage = (boolean) $realUsage;
38 | $this->useFormatting = (boolean) $useFormatting;
39 | }
40 |
41 | /**
42 | * Formats bytes into a human readable string if $this->useFormatting is true, otherwise return $bytes as is
43 | *
44 | * @param int $bytes
45 | * @return string|int Formatted string if $this->useFormatting is true, otherwise return $bytes as is
46 | */
47 | protected function formatBytes($bytes)
48 | {
49 | $bytes = (int) $bytes;
50 |
51 | if (!$this->useFormatting) {
52 | return $bytes;
53 | }
54 |
55 | if ($bytes > 1024 * 1024) {
56 | return round($bytes / 1024 / 1024, 2).' MB';
57 | } elseif ($bytes > 1024) {
58 | return round($bytes / 1024, 2).' KB';
59 | }
60 |
61 | return $bytes . ' B';
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Logger/Monolog/Processor/MemoryUsageProcessor.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Processor;
13 |
14 | /**
15 | * Injects memory_get_usage in all records
16 | *
17 | * @see Monolog\Processor\MemoryProcessor::__construct() for options
18 | * @author Rob Jensen
19 | */
20 | class MemoryUsageProcessor extends MemoryProcessor
21 | {
22 | /**
23 | * @param array $record
24 | * @return array
25 | */
26 | public function __invoke(array $record)
27 | {
28 | $bytes = memory_get_usage($this->realUsage);
29 | $formatted = $this->formatBytes($bytes);
30 |
31 | $record['extra']['memory_usage'] = $formatted;
32 |
33 | return $record;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Logger/Monolog/Processor/ProcessIdProcessor.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Processor;
13 |
14 | /**
15 | * Adds value of getmypid into records
16 | *
17 | * @author Andreas Hörnicke
18 | */
19 | class ProcessIdProcessor
20 | {
21 | /**
22 | * @param array $record
23 | * @return array
24 | */
25 | public function __invoke(array $record)
26 | {
27 | $record['extra']['process_id'] = getmypid();
28 |
29 | return $record;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Logger/Monolog/Processor/PsrLogMessageProcessor.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Processor;
13 |
14 | /**
15 | * Processes a record's message according to PSR-3 rules
16 | *
17 | * It replaces {foo} with the value from $context['foo']
18 | *
19 | * @author Jordi Boggiano
20 | */
21 | class PsrLogMessageProcessor
22 | {
23 | /**
24 | * @param array $record
25 | * @return array
26 | */
27 | public function __invoke(array $record)
28 | {
29 | if (false === strpos($record['message'], '{')) {
30 | return $record;
31 | }
32 |
33 | $replacements = array();
34 | foreach ($record['context'] as $key => $val) {
35 | if (is_null($val) || is_scalar($val) || (is_object($val) && method_exists($val, "__toString"))) {
36 | $replacements['{'.$key.'}'] = $val;
37 | } elseif (is_object($val)) {
38 | $replacements['{'.$key.'}'] = '[object '.get_class($val).']';
39 | } else {
40 | $replacements['{'.$key.'}'] = '['.gettype($val).']';
41 | }
42 | }
43 |
44 | $record['message'] = strtr($record['message'], $replacements);
45 |
46 | return $record;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Logger/Monolog/Processor/TagProcessor.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Processor;
13 |
14 | /**
15 | * Adds a tags array into record
16 | *
17 | * @author Martijn Riemers
18 | */
19 | class TagProcessor
20 | {
21 | private $tags;
22 |
23 | public function __construct(array $tags = array())
24 | {
25 | $this->setTags($tags);
26 | }
27 |
28 | public function addTags(array $tags = array())
29 | {
30 | $this->tags = array_merge($this->tags, $tags);
31 | }
32 |
33 | public function setTags(array $tags = array())
34 | {
35 | $this->tags = $tags;
36 | }
37 |
38 | public function __invoke(array $record)
39 | {
40 | $record['extra']['tags'] = $this->tags;
41 |
42 | return $record;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Logger/Monolog/Processor/UidProcessor.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Processor;
13 |
14 | /**
15 | * Adds a unique identifier into records
16 | *
17 | * @author Simon Mönch
18 | */
19 | class UidProcessor
20 | {
21 | private $uid;
22 |
23 | public function __construct($length = 7)
24 | {
25 | if (!is_int($length) || $length > 32 || $length < 1) {
26 | throw new \InvalidArgumentException('The uid length must be an integer between 1 and 32');
27 | }
28 |
29 | $this->uid = substr(hash('md5', uniqid('', true)), 0, $length);
30 | }
31 |
32 | public function __invoke(array $record)
33 | {
34 | $record['extra']['uid'] = $this->uid;
35 |
36 | return $record;
37 | }
38 |
39 | /**
40 | * @return string
41 | */
42 | public function getUid()
43 | {
44 | return $this->uid;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Logger/Monolog/Processor/WebProcessor.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Monolog\Processor;
13 |
14 | /**
15 | * Injects url/method and remote IP of the current web request in all records
16 | *
17 | * @author Jordi Boggiano
18 | */
19 | class WebProcessor
20 | {
21 | /**
22 | * @var array|\ArrayAccess
23 | */
24 | protected $serverData;
25 |
26 | /**
27 | * Default fields
28 | *
29 | * Array is structured as [key in record.extra => key in $serverData]
30 | *
31 | * @var array
32 | */
33 | protected $extraFields = array(
34 | 'url' => 'REQUEST_URI',
35 | 'ip' => 'REMOTE_ADDR',
36 | 'http_method' => 'REQUEST_METHOD',
37 | 'server' => 'SERVER_NAME',
38 | 'referrer' => 'HTTP_REFERER',
39 | );
40 |
41 | /**
42 | * @param array|\ArrayAccess $serverData Array or object w/ ArrayAccess that provides access to the $_SERVER data
43 | * @param array|null $extraFields Field names and the related key inside $serverData to be added. If not provided it defaults to: url, ip, http_method, server, referrer
44 | */
45 | public function __construct($serverData = null, array $extraFields = null)
46 | {
47 | if (null === $serverData) {
48 | $this->serverData = &$_SERVER;
49 | } elseif (is_array($serverData) || $serverData instanceof \ArrayAccess) {
50 | $this->serverData = $serverData;
51 | } else {
52 | throw new \UnexpectedValueException('$serverData must be an array or object implementing ArrayAccess.');
53 | }
54 |
55 | if (null !== $extraFields) {
56 | if (isset($extraFields[0])) {
57 | foreach (array_keys($this->extraFields) as $fieldName) {
58 | if (!in_array($fieldName, $extraFields)) {
59 | unset($this->extraFields[$fieldName]);
60 | }
61 | }
62 | } else {
63 | $this->extraFields = $extraFields;
64 | }
65 | }
66 | }
67 |
68 | /**
69 | * @param array $record
70 | * @return array
71 | */
72 | public function __invoke(array $record)
73 | {
74 | // skip processing if for some reason request data
75 | // is not present (CLI or wonky SAPIs)
76 | if (!isset($this->serverData['REQUEST_URI'])) {
77 | return $record;
78 | }
79 |
80 | $record['extra'] = $this->appendExtraFields($record['extra']);
81 |
82 | return $record;
83 | }
84 |
85 | /**
86 | * @param string $extraName
87 | * @param string $serverName
88 | * @return $this
89 | */
90 | public function addExtraField($extraName, $serverName)
91 | {
92 | $this->extraFields[$extraName] = $serverName;
93 |
94 | return $this;
95 | }
96 |
97 | /**
98 | * @param array $extra
99 | * @return array
100 | */
101 | private function appendExtraFields(array $extra)
102 | {
103 | foreach ($this->extraFields as $extraName => $serverName) {
104 | $extra[$extraName] = isset($this->serverData[$serverName]) ? $this->serverData[$serverName] : null;
105 | }
106 |
107 | if (isset($this->serverData['UNIQUE_ID'])) {
108 | $extra['unique_id'] = $this->serverData['UNIQUE_ID'];
109 | }
110 |
111 | return $extra;
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/Logger/Psr/Log/LogLevel.php:
--------------------------------------------------------------------------------
1 | transport = 'udp';
38 | $worker->count = 2;
39 | $worker->name = 'LoggerServer';
40 | $worker->onMessage = array (
41 | $this,
42 | 'onMessage'
43 | );
44 | $time = date ( $this->logger_name_dataFormat );
45 | $this->stream = new StreamHandler ( $this->dir . "/$time.log", $this->logger_level );
46 | $this->stream->setFormatter ( new LineFormatter () );
47 | }
48 |
49 | /**
50 | * onMessage.
51 | *
52 | * @param TcpConnection $connection
53 | * @param string $data
54 | */
55 | public function onMessage($connection, $data) {
56 | if (! $data) {
57 | return;
58 | }
59 | $data = unserialize ( $data );
60 | $time = date ( 'Y-m-d H:i:s' );
61 | $logger_name = $data ['logger_name'];
62 | $logger_level = $data ['logger_level'];
63 | $logger_message = $data ['logger_message'];
64 | $logger = $this->getLoger ( $logger_name );
65 | $logger->addRecord ( $logger_level, $logger_message );
66 | echo "[$time][$logger_name]" . $logger_message . "\n";
67 | }
68 |
69 | private function getLoger($loger_name) {
70 | if (! array_key_exists ( $loger_name, $this->logerlist )) {
71 | $logger = new Logger ( $loger_name );
72 | $logger->pushHandler ( $this->stream );
73 | $this->logerlist [$loger_name] = $logger;
74 | }
75 | return $this->logerlist [$loger_name];
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CI-worker
2 | 基于workerman翻作的CI框架,与CI框架的函数保持兼容,结构保持一致。目前仅支持CI的model和controll,view并没有做支持。
3 | #如何使用
4 | 参考CI框架使用
5 | route由于效率问题被固定为‘test/test’这种类型。并没有引入Route和URL类,
6 | 理论上将原来的CI框架中的model,controll,config,help,lib等复制到对应的文件夹即可使用。
7 | 部分CI的类库没有默认加入到框架中,可自行放入,但切记涉及到core中未包含的类对象是无法访问的。
8 | Log,Input,Output进行了深度优化和CI原本的不一致
9 | workeman进行了少量的修改,主要为Http这个文件的一些修改
10 | #优化
11 | 不要在你的控制器方法中使用load,load应该被移到__construct中,__CI_construct为了保留CI的习惯这个方法在每次调用控制器方法前都会执行,同样这里只能做验证获取数据等操作不要使用load
12 | CI原版代码中大量使用了魔术方法,尽量不要使用魔术方法非常影响效率,在__construct中尽量缓存数据。
13 | #性能
14 | i3 4核 8G php7 event.so 环境下,裸跑workeman http协议请求能达到11W/s
15 | CI-worker简易逻辑,仅route获取get,post,header等数据测试结果在8.5W/s。
16 | 秒杀CI框架。
17 | 另外为了测试workerman http解析时效率问题,用swoole框架进行的对比发现swoole的http服务器性能为10W/s还略不如workerman。
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Workerman/.gitignore:
--------------------------------------------------------------------------------
1 | logs
2 | .buildpath
3 | .project
4 | .settings
5 | .idea
--------------------------------------------------------------------------------
/Workerman/Autoloader.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman;
15 |
16 | /**
17 | * Autoload.
18 | */
19 | class Autoloader
20 | {
21 | /**
22 | * Autoload root path.
23 | *
24 | * @var string
25 | */
26 | protected static $_autoloadRootPath = '';
27 |
28 | /**
29 | * Set autoload root path.
30 | *
31 | * @param string $root_path
32 | * @return void
33 | */
34 | public static function setRootPath($root_path)
35 | {
36 | self::$_autoloadRootPath = $root_path;
37 | }
38 |
39 | /**
40 | * Load files by namespace.
41 | *
42 | * @param string $name
43 | * @return boolean
44 | */
45 | public static function loadByNamespace($name)
46 | {
47 | $class_path = str_replace('\\', DIRECTORY_SEPARATOR, $name);
48 | if (strpos($name, 'Workerman\\') === 0) {
49 | $class_file = __DIR__ . substr($class_path, strlen('Workerman')) . '.php';
50 | } else {
51 | if (self::$_autoloadRootPath) {
52 | $class_file = self::$_autoloadRootPath . DIRECTORY_SEPARATOR . $class_path . '.php';
53 | }
54 | if (empty($class_file) || !is_file($class_file)) {
55 | $class_file = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . "$class_path.php";
56 | }
57 | }
58 |
59 | if (is_file($class_file)) {
60 | require_once($class_file);
61 | if (class_exists($name, false)) {
62 | return true;
63 | }
64 | }
65 | return false;
66 | }
67 | }
68 |
69 | spl_autoload_register('\Workerman\Autoloader::loadByNamespace');
--------------------------------------------------------------------------------
/Workerman/Connection/ConnectionInterface.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Connection;
15 |
16 | /**
17 | * ConnectionInterface.
18 | */
19 | abstract class ConnectionInterface
20 | {
21 | /**
22 | * Statistics for status command.
23 | *
24 | * @var array
25 | */
26 | public static $statistics = array(
27 | 'connection_count' => 0,
28 | 'total_request' => 0,
29 | 'throw_exception' => 0,
30 | 'send_fail' => 0,
31 | );
32 |
33 | /**
34 | * Emitted when data is received.
35 | *
36 | * @var callback
37 | */
38 | public $onMessage = null;
39 |
40 | /**
41 | * Emitted when the other end of the socket sends a FIN packet.
42 | *
43 | * @var callback
44 | */
45 | public $onClose = null;
46 |
47 | /**
48 | * Emitted when an error occurs with connection.
49 | *
50 | * @var callback
51 | */
52 | public $onError = null;
53 |
54 | /**
55 | * Sends data on the connection.
56 | *
57 | * @param string $send_buffer
58 | * @return void|boolean
59 | */
60 | abstract public function send($send_buffer);
61 |
62 | /**
63 | * Get remote IP.
64 | *
65 | * @return string
66 | */
67 | abstract public function getRemoteIp();
68 |
69 | /**
70 | * Get remote port.
71 | *
72 | * @return int
73 | */
74 | abstract public function getRemotePort();
75 |
76 | /**
77 | * Close connection.
78 | *
79 | * @param $data
80 | * @return void
81 | */
82 | abstract public function close($data = null);
83 | }
84 |
--------------------------------------------------------------------------------
/Workerman/Connection/UdpConnection.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Connection;
15 |
16 | /**
17 | * UdpConnection.
18 | */
19 | class UdpConnection extends ConnectionInterface
20 | {
21 | /**
22 | * Application layer protocol.
23 | * The format is like this Workerman\\Protocols\\Http.
24 | *
25 | * @var \Workerman\Protocols\ProtocolInterface
26 | */
27 | public $protocol = null;
28 |
29 | /**
30 | * Udp socket.
31 | *
32 | * @var resource
33 | */
34 | protected $_socket = null;
35 |
36 | /**
37 | * Remote ip.
38 | *
39 | * @var string
40 | */
41 | protected $_remoteIp = '';
42 |
43 | /**
44 | * Remote port.
45 | *
46 | * @var int
47 | */
48 | protected $_remotePort = 0;
49 |
50 | /**
51 | * Remote address.
52 | *
53 | * @var string
54 | */
55 | protected $_remoteAddress = '';
56 |
57 | /**
58 | * Construct.
59 | *
60 | * @param resource $socket
61 | * @param string $remote_address
62 | */
63 | public function __construct($socket, $remote_address)
64 | {
65 | $this->_socket = $socket;
66 | $this->_remoteAddress = $remote_address;
67 | }
68 |
69 | /**
70 | * Sends data on the connection.
71 | *
72 | * @param string $send_buffer
73 | * @param bool $raw
74 | * @return void|boolean
75 | */
76 | public function send($send_buffer, $raw = false)
77 | {
78 | if (false === $raw && $this->protocol) {
79 | $parser = $this->protocol;
80 | $send_buffer = $parser::encode($send_buffer, $this);
81 | if ($send_buffer === '') {
82 | return null;
83 | }
84 | }
85 | return strlen($send_buffer) === stream_socket_sendto($this->_socket, $send_buffer, 0, $this->_remoteAddress);
86 | }
87 |
88 | /**
89 | * Get remote IP.
90 | *
91 | * @return string
92 | */
93 | public function getRemoteIp()
94 | {
95 | if (!$this->_remoteIp) {
96 | list($this->_remoteIp, $this->_remotePort) = explode(':', $this->_remoteAddress, 2);
97 | }
98 | return $this->_remoteIp;
99 | }
100 |
101 | /**
102 | * Get remote port.
103 | *
104 | * @return int
105 | */
106 | public function getRemotePort()
107 | {
108 | if (!$this->_remotePort) {
109 | list($this->_remoteIp, $this->_remotePort) = explode(':', $this->_remoteAddress, 2);
110 | }
111 | return $this->_remotePort;
112 | }
113 |
114 | /**
115 | * Close connection.
116 | *
117 | * @param mixed $data
118 | * @return bool
119 | */
120 | public function close($data = null)
121 | {
122 | if ($data !== null) {
123 | $this->send($data);
124 | }
125 | return true;
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/Workerman/Events/EventInterface.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Events;
15 |
16 | interface EventInterface
17 | {
18 | /**
19 | * Read event.
20 | *
21 | * @var int
22 | */
23 | const EV_READ = 1;
24 |
25 | /**
26 | * Write event.
27 | *
28 | * @var int
29 | */
30 | const EV_WRITE = 2;
31 |
32 | /**
33 | * Signal event.
34 | *
35 | * @var int
36 | */
37 | const EV_SIGNAL = 4;
38 |
39 | /**
40 | * Timer event.
41 | *
42 | * @var int
43 | */
44 | const EV_TIMER = 8;
45 |
46 | /**
47 | * Timer once event.
48 | *
49 | * @var int
50 | */
51 | const EV_TIMER_ONCE = 16;
52 |
53 | /**
54 | * Add event listener to event loop.
55 | *
56 | * @param mixed $fd
57 | * @param int $flag
58 | * @param callable $func
59 | * @param mixed $args
60 | * @return bool
61 | */
62 | public function add($fd, $flag, $func, $args = null);
63 |
64 | /**
65 | * Remove event listener from event loop.
66 | *
67 | * @param mixed $fd
68 | * @param int $flag
69 | * @return bool
70 | */
71 | public function del($fd, $flag);
72 |
73 | /**
74 | * Remove all timers.
75 | *
76 | * @return void
77 | */
78 | public function clearAllTimer();
79 |
80 | /**
81 | * Main loop.
82 | *
83 | * @return void
84 | */
85 | public function loop();
86 | }
87 |
--------------------------------------------------------------------------------
/Workerman/Lib/Constants.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 |
15 | // Date.timezone
16 | if (!ini_get('date.timezone')) {
17 | date_default_timezone_set('Asia/Shanghai');
18 | }
19 | // Display errors.
20 | ini_set('display_errors', 'on');
21 | // Reporting all.
22 | error_reporting(E_ALL);
23 |
24 | // For onError callback.
25 | define('WORKERMAN_CONNECT_FAIL', 1);
26 | // For onError callback.
27 | define('WORKERMAN_SEND_FAIL', 2);
28 |
29 | // Compatible with php7
30 | if(!class_exists('Error'))
31 | {
32 | class Error extends Exception
33 | {
34 | }
35 | }
--------------------------------------------------------------------------------
/Workerman/MIT-LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2009-2015 walkor and contributors (see https://github.com/walkor/workerman/contributors)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Workerman/Protocols/Frame.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Protocols;
15 |
16 | use Workerman\Connection\TcpConnection;
17 |
18 | /**
19 | * Frame Protocol.
20 | */
21 | class Frame
22 | {
23 | /**
24 | * Check the integrity of the package.
25 | *
26 | * @param string $buffer
27 | * @param TcpConnection $connection
28 | * @return int
29 | */
30 | public static function input($buffer, TcpConnection $connection)
31 | {
32 | if (strlen($buffer) < 4) {
33 | return 0;
34 | }
35 | $unpack_data = unpack('Ntotal_length', $buffer);
36 | return $unpack_data['total_length'];
37 | }
38 |
39 | /**
40 | * Encode.
41 | *
42 | * @param string $buffer
43 | * @return string
44 | */
45 | public static function decode($buffer)
46 | {
47 | return substr($buffer, 4);
48 | }
49 |
50 | /**
51 | * Decode.
52 | *
53 | * @param string $buffer
54 | * @return string
55 | */
56 | public static function encode($buffer)
57 | {
58 | $total_length = 4 + strlen($buffer);
59 | return pack('N', $total_length) . $buffer;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Workerman/Protocols/Http/mime.types:
--------------------------------------------------------------------------------
1 |
2 | types {
3 | text/html html htm shtml;
4 | text/css css;
5 | text/xml xml;
6 | image/gif gif;
7 | image/jpeg jpeg jpg;
8 | application/x-javascript js;
9 | application/atom+xml atom;
10 | application/rss+xml rss;
11 |
12 | text/mathml mml;
13 | text/plain txt;
14 | text/vnd.sun.j2me.app-descriptor jad;
15 | text/vnd.wap.wml wml;
16 | text/x-component htc;
17 |
18 | image/png png;
19 | image/tiff tif tiff;
20 | image/vnd.wap.wbmp wbmp;
21 | image/x-icon ico;
22 | image/x-jng jng;
23 | image/x-ms-bmp bmp;
24 | image/svg+xml svg svgz;
25 | image/webp webp;
26 |
27 | application/java-archive jar war ear;
28 | application/mac-binhex40 hqx;
29 | application/msword doc;
30 | application/pdf pdf;
31 | application/postscript ps eps ai;
32 | application/rtf rtf;
33 | application/vnd.ms-excel xls;
34 | application/vnd.ms-powerpoint ppt;
35 | application/vnd.wap.wmlc wmlc;
36 | application/vnd.google-earth.kml+xml kml;
37 | application/vnd.google-earth.kmz kmz;
38 | application/x-7z-compressed 7z;
39 | application/x-cocoa cco;
40 | application/x-java-archive-diff jardiff;
41 | application/x-java-jnlp-file jnlp;
42 | application/x-makeself run;
43 | application/x-perl pl pm;
44 | application/x-pilot prc pdb;
45 | application/x-rar-compressed rar;
46 | application/x-redhat-package-manager rpm;
47 | application/x-sea sea;
48 | application/x-shockwave-flash swf;
49 | application/x-stuffit sit;
50 | application/x-tcl tcl tk;
51 | application/x-x509-ca-cert der pem crt;
52 | application/x-xpinstall xpi;
53 | application/xhtml+xml xhtml;
54 | application/zip zip;
55 |
56 | application/octet-stream bin exe dll;
57 | application/octet-stream deb;
58 | application/octet-stream dmg;
59 | application/octet-stream eot;
60 | application/octet-stream iso img;
61 | application/octet-stream msi msp msm;
62 |
63 | audio/midi mid midi kar;
64 | audio/mpeg mp3;
65 | audio/ogg ogg;
66 | audio/x-m4a m4a;
67 | audio/x-realaudio ra;
68 |
69 | video/3gpp 3gpp 3gp;
70 | video/mp4 mp4;
71 | video/mpeg mpeg mpg;
72 | video/quicktime mov;
73 | video/webm webm;
74 | video/x-flv flv;
75 | video/x-m4v m4v;
76 | video/x-mng mng;
77 | video/x-ms-asf asx asf;
78 | video/x-ms-wmv wmv;
79 | video/x-msvideo avi;
80 | }
81 |
--------------------------------------------------------------------------------
/Workerman/Protocols/ProtocolInterface.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Protocols;
15 |
16 | use Workerman\Connection\ConnectionInterface;
17 |
18 | /**
19 | * Protocol interface
20 | */
21 | interface ProtocolInterface
22 | {
23 | /**
24 | * Check the integrity of the package.
25 | * Please return the length of package.
26 | * If length is unknow please return 0 that mean wating more data.
27 | * If the package has something wrong please return false the connection will be closed.
28 | *
29 | * @param ConnectionInterface $connection
30 | * @param string $recv_buffer
31 | * @return int|false
32 | */
33 | public static function input($recv_buffer, ConnectionInterface $connection);
34 |
35 | /**
36 | * Decode package and emit onMessage($message) callback, $message is the result that decode returned.
37 | *
38 | * @param ConnectionInterface $connection
39 | * @param string $recv_buffer
40 | * @return mixed
41 | */
42 | public static function decode($recv_buffer, ConnectionInterface $connection);
43 |
44 | /**
45 | * Encode package brefore sending to client.
46 | *
47 | * @param ConnectionInterface $connection
48 | * @param mixed $data
49 | * @return string
50 | */
51 | public static function encode($data, ConnectionInterface $connection);
52 | }
53 |
--------------------------------------------------------------------------------
/Workerman/Protocols/Text.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright walkor
11 | * @link http://www.workerman.net/
12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 | */
14 | namespace Workerman\Protocols;
15 |
16 | use Workerman\Connection\TcpConnection;
17 |
18 | /**
19 | * Text Protocol.
20 | */
21 | class Text
22 | {
23 | /**
24 | * Check the integrity of the package.
25 | *
26 | * @param string $buffer
27 | * @param TcpConnection $connection
28 | * @return int
29 | */
30 | public static function input($buffer, TcpConnection $connection)
31 | {
32 | // Judge whether the package length exceeds the limit.
33 | if (strlen($buffer) >= TcpConnection::$maxPackageSize) {
34 | $connection->close();
35 | return 0;
36 | }
37 | // Find the position of "\n".
38 | $pos = strpos($buffer, "\n");
39 | // No "\n", packet length is unknown, continue to wait for the data so return 0.
40 | if ($pos === false) {
41 | return 0;
42 | }
43 | // Return the current package length.
44 | return $pos + 1;
45 | }
46 |
47 | /**
48 | * Encode.
49 | *
50 | * @param string $buffer
51 | * @return string
52 | */
53 | public static function encode($buffer)
54 | {
55 | // Add "\n"
56 | return $buffer . "\n";
57 | }
58 |
59 | /**
60 | * Decode.
61 | *
62 | * @param string $buffer
63 | * @return string
64 | */
65 | public static function decode($buffer)
66 | {
67 | // Remove "\n"
68 | return trim($buffer);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Workerman/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "workerman/workerman",
3 | "type" : "project",
4 | "keywords": ["event-loop", "asynchronous"],
5 | "homepage": "http://www.workerman.net",
6 | "license" : "MIT",
7 | "description": "An asynchronous event driven PHP framework for easily building fast, scalable network applications.",
8 | "authors" : [
9 | {
10 | "name" : "walkor",
11 | "email" : "walkor@workerman.net",
12 | "homepage" : "http://www.workerman.net",
13 | "role": "Developer"
14 | }
15 | ],
16 | "support" : {
17 | "email" : "walkor@workerman.net",
18 | "issues": "https://github.com/walkor/workerman/issues",
19 | "forum" : "http://wenda.workerman.net/",
20 | "wiki" : "http://doc3.workerman.net/index.html",
21 | "source": "https://github.com/walkor/workerman"
22 | },
23 | "require": {
24 | "php": ">=5.3"
25 | },
26 | "suggest": {
27 | "ext-libevent": "For better performance."
28 | },
29 | "autoload": {
30 | "psr-4": {"Workerman\\": "./"}
31 | },
32 | "minimum-stability":"dev"
33 | }
34 |
--------------------------------------------------------------------------------
/start.php:
--------------------------------------------------------------------------------
1 |