Use a custom logger for every instance, create Magic class for shared instance data

This commit is contained in:
Daniil Gentili 2018-04-08 17:44:01 +00:00
parent 3538aabda8
commit 73e97fc620
12 changed files with 154 additions and 115 deletions

8
madeline.php Normal file
View File

@ -0,0 +1,8 @@
<?php
if (!file_exists('madeline.phar') || !file_exists('madeline.phar.version') || file_get_contents('madeline.phar.version') !== file_get_contents('https://phar.madelineproto.xyz/release?v=new')) {
file_put_contents('madeline.phar', file_get_contents('https://phar.madelineproto.xyz/madeline.phar?v=new'));
file_put_contents('madeline.phar.version', file_get_contents('https://phar.madelineproto.xyz/release?v=new'));
}
require 'madeline.phar';

View File

@ -47,7 +47,7 @@ class API extends APIFactory
flock($realpaths['lockfile'], LOCK_UN);
fclose($realpaths['lockfile']);
}
\danog\MadelineProto\Logger::class_exists();
\danog\MadelineProto\Magic::class_exists();
try {
$unserialized = unserialize($tounserialize);
@ -110,7 +110,7 @@ class API extends APIFactory
public function __destruct()
{
if (\danog\MadelineProto\Logger::$has_thread && is_object(\Thread::getCurrentThread()) || Logger::is_fork()) {
if (\danog\MadelineProto\Magic::$has_thread && is_object(\Thread::getCurrentThread()) || Magic::is_fork()) {
return;
}
$this->serialize();
@ -136,13 +136,13 @@ class API extends APIFactory
public function __set($name, $value)
{
if ($name === 'settings') {
if (Logger::is_fork() && !Logger::$processed_fork) {
if (Magic::is_fork() && !Magic::$processed_fork) {
\danog\MadelineProto\Logger::log('Detected fork');
$this->API->reset_session();
foreach ($this->API->datacenter->sockets as $datacenter) {
$datacenter->close_and_reopen();
}
Logger::$processed_fork = true;
Magic::$processed_fork = true;
}
return $this->API->__construct(array_replace_recursive($this->API->settings, $value));

View File

@ -118,13 +118,13 @@ class APIFactory
public function __call($name, $arguments)
{
if (Logger::is_fork() && !Logger::$processed_fork) {
if (Magic::is_fork() && !Magic::$processed_fork) {
\danog\MadelineProto\Logger::log('Detected fork');
$this->API->reset_session();
foreach ($this->API->datacenter->sockets as $datacenter) {
$datacenter->close_and_reopen();
}
Logger::$processed_fork = true;
Magic::$processed_fork = true;
}
if ($this->API->setdem) {

View File

@ -37,13 +37,13 @@ class EventHandler extends APIFactory
public function __set($name, $value)
{
if ($name === 'settings') {
if (Logger::is_fork() && !Logger::$processed_fork) {
if (Magic::is_fork() && !Magic::$processed_fork) {
\danog\MadelineProto\Logger::log('Detected fork');
$this->API->reset_session();
foreach ($this->API->datacenter->sockets as $datacenter) {
$datacenter->close_and_reopen();
}
Logger::$processed_fork = true;
Magic::$processed_fork = true;
}
return $this->API->__construct(array_replace_recursive($this->API->settings, $value));

View File

@ -22,24 +22,15 @@ class Logger
const background = ['default' => 49, 'black' => 40, 'red' => 41, 'magenta' => 45, 'yellow' => 43, 'green' => 42, 'blue' => 44, 'cyan' => 46, 'light_gray' => 47, 'dark_gray' => 100, 'light_red' => 101, 'light_green' => 102, 'light_yellow' => 103, 'light_blue' => 104, 'light_magenta' => 105, 'light_cyan' => 106, 'white' => 107];
const set = ['bold' => 1, 'dim' => 2, 'underlined' => 3, 'blink' => 4, 'reverse' => 5, 'hidden' => 6];
const reset = ['all' => 0, 'bold' => 21, 'dim' => 22, 'underlined' => 24, 'blink' => 25, 'reverse' => 26, 'hidden' => 28];
public static $storage = [];
public static $mode = 0;
public static $optional = null;
public static $prefix = '';
public static $level = 3;
public static $has_thread = false;
public static $BIG_ENDIAN = false;
public static $bigint = true;
public static $colors = [];
public static $isatty = false;
public static $is_fork = false;
public static $can_getmypid = true;
public static $processed_fork = false;
public static $ipv6;
private static $pid;
public static $inited = false;
public $mode = 0;
public $optional = null;
public $prefix = '';
public $level = 3;
public $colors = [];
public static $default;
const ULTRA_VERBOSE = 5;
const VERBOSE = 4;
const NOTICE = 3;
@ -47,58 +38,8 @@ class Logger
const ERROR = 1;
const FATAL_ERROR = 0;
public static function class_exists()
{
if (!self::$inited) {
self::$has_thread = class_exists('\\Thread') && method_exists('\\Thread', 'getCurrentThread');
self::$BIG_ENDIAN = pack('L', 1) === pack('N', 1);
self::$bigint = PHP_INT_SIZE < 8;
self::$ipv6 = (bool) strlen(@file_get_contents('http://v6.ipv6-test.com/api/myip.php', false, stream_context_create(['http' => ['timeout' => 1]]))) > 0;
preg_match('/const V = (\\d+);/', @file_get_contents('https://raw.githubusercontent.com/danog/MadelineProto/master/src/danog/MadelineProto/MTProto.php'), $matches);
if (isset($matches[1]) && \danog\MadelineProto\MTProto::V < (int) $matches[1]) {
throw new \danog\MadelineProto\Exception(hex2bin(\danog\MadelineProto\Lang::$current_lang['v_error']), 0, null, 'MadelineProto', 1);
}
if (class_exists('\\danog\\MadelineProto\\VoIP')) {
if (!defined('\\danog\\MadelineProto\\VoIP::PHP_LIBTGVOIP_VERSION') || \danog\MadelineProto\VoIP::PHP_LIBTGVOIP_VERSION !== '1.1.2') {
throw new \danog\MadelineProto\Exception(hex2bin(\danog\MadelineProto\Lang::$current_lang['v_tgerror']), 0, null, 'MadelineProto', 1);
}
}
self::$colors[self::ULTRA_VERBOSE] = implode(';', [self::foreground['light_gray'], self::set['dim']]);
self::$colors[self::VERBOSE] = implode(';', [self::foreground['green'], self::set['bold']]);
self::$colors[self::NOTICE] = implode(';', [self::foreground['yellow'], self::set['bold']]);
self::$colors[self::WARNING] = implode(';', [self::foreground['white'], self::set['dim'], self::background['red']]);
self::$colors[self::ERROR] = implode(';', [self::foreground['white'], self::set['bold'], self::background['red']]);
self::$colors[self::FATAL_ERROR] = implode(';', [self::foreground['red'], self::set['bold'], self::background['light_gray']]);
try {
self::$isatty = defined('STDOUT') && function_exists('posix_isatty') && posix_isatty(STDOUT);
} catch (\danog\MadelineProto\Exception $e) {
}
self::$can_getmypid = !(isset($_SERVER['SERVER_ADMIN']) && strpos($_SERVER['SERVER_ADMIN'], 'altervista.org'));
self::$inited = true;
}
}
public static function is_fork()
{
if (self::$is_fork) {
return true;
}
if (!self::$can_getmypid) {
return false;
}
try {
if (self::$pid === null) {
self::$pid = getmypid();
}
return self::$is_fork = self::$pid !== getmypid();
} catch (\danog\MadelineProto\Exception $e) {
return self::$can_getmypid = false;
}
}
/*
* Constructor function
* Accepts various logger modes:
@ -109,31 +50,45 @@ class Logger
* 4 - Call callable provided in logger_param. logger_param must accept two parameters: array $message, int $level
* $message is an array containing the messages the log, $level, is the logging level
*/
public static function constructor($mode, $optional = null, $prefix = '', $level = self::NOTICE)
public static function constructor($mode, $optional = null, $prefix = '', $level = self::NOTICE) {
self::$default = new Logger($mode, $optional, $prefix, $level);
}
public function __construct($mode, $optional = null, $prefix = '', $level = self::NOTICE)
{
if ($mode === null) {
throw new Exception(\danog\MadelineProto\Lang::$current_lang['no_mode_specified']);
}
self::$mode = $mode;
self::$optional = $mode == 2 ? Absolute::absolute($optional) : $optional;
self::$prefix = $prefix === '' ? '' : ', '.$prefix;
self::$level = $level;
self::class_exists();
$this->mode = $mode;
$this->optional = $mode == 2 ? Absolute::absolute($optional) : $optional;
$this->prefix = $prefix === '' ? '' : ', '.$prefix;
$this->level = $level;
$this->colors[Logger::ULTRA_VERBOSE] = implode(';', [Logger::foreground['light_gray'], Logger::set['dim']]);
$this->colors[Logger::VERBOSE] = implode(';', [Logger::foreground['green'], Logger::set['bold']]);
$this->colors[Logger::NOTICE] = implode(';', [Logger::foreground['yellow'], Logger::set['bold']]);
$this->colors[Logger::WARNING] = implode(';', [Logger::foreground['white'], Logger::set['dim'], Logger::background['red']]);
$this->colors[Logger::ERROR] = implode(';', [Logger::foreground['white'], Logger::set['bold'], Logger::background['red']]);
$this->colors[Logger::FATAL_ERROR] = implode(';', [Logger::foreground['red'], Logger::set['bold'], Logger::background['light_gray']]);
}
public static function log($param, $level = self::NOTICE)
{
if ($level > self::$level || self::$mode === 0) {
if (!is_null(self::$default)) {
self::$default->logger($param, $level, basename(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1)[0]['file'], '.php'));
}
}
public function logger($param, $level = self::NOTICE, $file = null) {
if ($level > $this->level || $this->mode === 0) {
return false;
}
if (self::$mode === 4) {
return call_user_func_array(self::$optional, [$param, $level]);
if ($this->mode === 4) {
return call_user_func_array($this->optional, [$param, $level]);
}
$prefix = self::$prefix;
if (\danog\MadelineProto\Logger::$has_thread && is_object(\Thread::getCurrentThread())) {
$prefix = $this->prefix;
if (\danog\MadelineProto\Magic::$has_thread && is_object(\Thread::getCurrentThread())) {
$prefix .= ' (t)';
}
if (\danog\MadelineProto\Logger::is_fork()) {
if (\danog\MadelineProto\Magic::is_fork()) {
$prefix .= ' (p)';
}
if (!is_string($param)) {
@ -144,19 +99,19 @@ class Logger
$param = $parame;
}*/
}
$param = str_pad(basename(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1)[0]['file'], '.php').$prefix.': ', 16 + strlen($prefix))."\t".$param;
/*if (self::$isatty) {
self::$mode = 3;
}*/
switch (self::$mode) {
if ($file === null) {
$file = basename(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1)[0]['file'], '.php');
}
$param = str_pad($file.$prefix.': ', 16 + strlen($prefix))."\t".$param;
switch ($this->mode) {
case 1:
error_log($param);
break;
case 2:
error_log($param.PHP_EOL, 3, self::$optional);
error_log($param.PHP_EOL, 3, $this->optional);
break;
case 3:
echo self::$isatty ? "\33[".self::$colors[$level].'m'.$param."\33[0m".PHP_EOL : $param.PHP_EOL;
echo Magic::$isatty ? "\33[".$this->colors[$level].'m'.$param."\33[0m".PHP_EOL : $param.PHP_EOL;
break;
}
}

View File

@ -111,7 +111,7 @@ class MTProto
public function __magic_construct($settings = [])
{
\danog\MadelineProto\Logger::class_exists();
\danog\MadelineProto\Magic::class_exists();
// Parse settings
$this->parse_settings($settings);
if (!defined('\\phpseclib\\Crypt\\Common\\SymmetricKey::MODE_IGE') || \phpseclib\Crypt\Common\SymmetricKey::MODE_IGE !== 6) {
@ -180,7 +180,7 @@ class MTProto
set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']);
set_exception_handler(['\\danog\\MadelineProto\\Serialization', 'serialize_all']);
$this->setup_logger();
if (\danog\MadelineProto\Logger::$has_thread && is_object(\Thread::getCurrentThread())) {
if (\danog\MadelineProto\Magic::$has_thread && is_object(\Thread::getCurrentThread())) {
return;
}
Lang::$current_lang = &Lang::$lang['en'];
@ -195,7 +195,7 @@ class MTProto
}
$this->altervista = isset($_SERVER['SERVER_ADMIN']) && strpos($_SERVER['SERVER_ADMIN'], 'altervista.org');
$this->settings['connection_settings']['all']['ipv6'] = \danog\MadelineProto\Logger::$ipv6;
$this->settings['connection_settings']['all']['ipv6'] = \danog\MadelineProto\Magic::$ipv6;
/*if (isset($this->settings['pwr']['update_handler']) && $this->settings['pwr']['update_handler'] === $this->settings['updates']['callback']) {
unset($this->settings['pwr']['update_handler']);
$this->updates = [];
@ -336,7 +336,7 @@ class MTProto
public function __destruct()
{
if (\danog\MadelineProto\Logger::$has_thread && is_object(\Thread::getCurrentThread())) {
if (\danog\MadelineProto\Magic::$has_thread && is_object(\Thread::getCurrentThread())) {
return;
}
}
@ -452,7 +452,7 @@ class MTProto
// can be tcp_full, tcp_abridged, tcp_intermediate, http, https, obfuscated2, udp (unsupported)
'test_mode' => false,
// decides whether to connect to the main telegram servers or to the testing servers (deep telegram)
'ipv6' => \danog\MadelineProto\Logger::$ipv6,
'ipv6' => \danog\MadelineProto\Magic::$ipv6,
// decides whether to use ipv6, ipv6 attribute of API attribute of API class contains autodetected boolean
'timeout' => 2,
// timeout for sockets

View File

@ -35,7 +35,7 @@ trait MsgIdHandler
if (!$new_message_id->divide($this->four)[1]->equals($this->zero)) {
throw new \danog\MadelineProto\Exception('Given message id ('.$new_message_id.') is not divisible by 4. Consider syncing your date.');
}
if (!\danog\MadelineProto\Logger::$has_thread && $new_message_id->compare($key = $this->get_max_id($aargs['datacenter'], false)) <= 0) {
if (!\danog\MadelineProto\Magic::$has_thread && $new_message_id->compare($key = $this->get_max_id($aargs['datacenter'], false)) <= 0) {
throw new \danog\MadelineProto\Exception('Given message id ('.$new_message_id.') is lower than or equal to the current limit ('.$key.'). Consider syncing your date.', 1);
}
if (count($this->datacenter->sockets[$aargs['datacenter']]->outgoing_messages) > $this->settings['msg_array_limit']['outgoing']) {

View File

@ -297,7 +297,7 @@ trait PeerHandler
}
if (is_numeric($id)) {
if (is_string($id)) {
$id = \danog\MadelineProto\Logger::$bigint ? (float) $id : (int) $id;
$id = \danog\MadelineProto\Magic::$bigint ? (float) $id : (int) $id;
}
if (!isset($this->chats[$id]) && $id < 0 && !$this->is_supergroup($id)) {
$this->method_call('messages.getFullChat', ['chat_id' => -$id], ['datacenter' => $this->datacenter->curdc]);

View File

@ -0,0 +1,76 @@
<?php
/*
Copyright 2016-2018 Daniil Gentili
(https://daniil.it)
This file is part of MadelineProto.
MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Affero General Public License for more details.
You should have received a copy of the GNU General Public License along with MadelineProto.
If not, see <http://www.gnu.org/licenses/>.
*/
namespace danog\MadelineProto;
class Magic
{
public static $storage = [];
public static $has_thread = false;
public static $BIG_ENDIAN = false;
public static $bigint = true;
public static $isatty = false;
public static $is_fork = false;
public static $can_getmypid = true;
public static $processed_fork = false;
public static $ipv6;
private static $pid;
public static $inited = false;
public static function class_exists()
{
if (!self::$inited) {
self::$has_thread = class_exists('\\Thread') && method_exists('\\Thread', 'getCurrentThread');
self::$BIG_ENDIAN = pack('L', 1) === pack('N', 1);
self::$bigint = PHP_INT_SIZE < 8;
self::$ipv6 = (bool) strlen(@file_get_contents('http://v6.ipv6-test.com/api/myip.php', false, stream_context_create(['http' => ['timeout' => 1]]))) > 0;
preg_match('/const V = (\\d+);/', @file_get_contents('https://raw.githubusercontent.com/danog/MadelineProto/master/src/danog/MadelineProto/MTProto.php'), $matches);
if (isset($matches[1]) && \danog\MadelineProto\MTProto::V < (int) $matches[1]) {
throw new \danog\MadelineProto\Exception(hex2bin(\danog\MadelineProto\Lang::$current_lang['v_error']), 0, null, 'MadelineProto', 1);
}
if (class_exists('\\danog\\MadelineProto\\VoIP')) {
if (!defined('\\danog\\MadelineProto\\VoIP::PHP_LIBTGVOIP_VERSION') || \danog\MadelineProto\VoIP::PHP_LIBTGVOIP_VERSION !== '1.1.2') {
throw new \danog\MadelineProto\Exception(hex2bin(\danog\MadelineProto\Lang::$current_lang['v_tgerror']), 0, null, 'MadelineProto', 1);
}
}
try {
self::$isatty = defined('STDOUT') && function_exists('posix_isatty') && posix_isatty(STDOUT);
} catch (\danog\MadelineProto\Exception $e) {
}
self::$can_getmypid = !(isset($_SERVER['SERVER_ADMIN']) && strpos($_SERVER['SERVER_ADMIN'], 'altervista.org'));
self::$inited = true;
}
}
public static function is_fork()
{
if (self::$is_fork) {
return true;
}
if (!self::$can_getmypid) {
return false;
}
try {
if (self::$pid === null) {
self::$pid = getmypid();
}
return self::$is_fork = self::$pid !== getmypid();
} catch (\danog\MadelineProto\Exception $e) {
return self::$can_getmypid = false;
}
}
}

View File

@ -235,7 +235,7 @@ class Handler extends \danog\MadelineProto\Connection
try {
$this->logging = true;
$message = ['_' => 'socketMessageLog', 'data' => $message, 'level' => $level, 'thread' => \danog\MadelineProto\Logger::$has_thread && is_object(\Thread::getCurrentThread()), 'process' => \danog\MadelineProto\Logger::is_fork(), 'file' => basename(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['file'], '.php')];
$message = ['_' => 'socketMessageLog', 'data' => $message, 'level' => $level, 'thread' => \danog\MadelineProto\Magic::$has_thread && is_object(\Thread::getCurrentThread()), 'process' => \danog\MadelineProto\Magic::is_fork(), 'file' => basename(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['file'], '.php')];
$this->send_message_safe($this->serialize_object(['type' => ''], $message, 'log'));
} finally {

View File

@ -564,7 +564,7 @@ trait TL
return stream_get_contents($stream, 8);
}
return \danog\MadelineProto\Logger::$bigint || isset($type['strlong']) ? stream_get_contents($stream, 8) : $this->unpack_signed_long(stream_get_contents($stream, 8));
return \danog\MadelineProto\Magic::$bigint || isset($type['strlong']) ? stream_get_contents($stream, 8) : $this->unpack_signed_long(stream_get_contents($stream, 8));
case 'double':
return $this->unpack_double(stream_get_contents($stream, 8));
case 'int128':

View File

@ -19,7 +19,7 @@ trait Tools
{
public function gen_vector_hash($ints)
{
if (\danog\MadelineProto\Logger::$bigint) {
if (\danog\MadelineProto\Magic::$bigint) {
$hash = new \phpseclib\Math\BigInteger(0);
foreach ($ints as $int) {
$hash = $hash->multiply($this->twozerotwosixone)->add($this->zeroeight)->add(new \phpseclib\Math\BigInteger($int))->divide($this->zeroeight)[1];
@ -53,7 +53,7 @@ trait Tools
public function array_cast_recursive($array, $force = false)
{
if (!\danog\MadelineProto\Logger::$has_thread && !$force) {
if (!\danog\MadelineProto\Magic::$has_thread && !$force) {
return $array;
}
if (is_array($array)) {
@ -74,7 +74,7 @@ trait Tools
throw new TL\Exception(\danog\MadelineProto\Lang::$current_lang['length_not_4']);
}
return unpack('l', \danog\MadelineProto\Logger::$BIG_ENDIAN ? strrev($value) : $value)[1];
return unpack('l', \danog\MadelineProto\Magic::$BIG_ENDIAN ? strrev($value) : $value)[1];
}
public function unpack_signed_long($value)
@ -83,7 +83,7 @@ trait Tools
throw new TL\Exception(\danog\MadelineProto\Lang::$current_lang['length_not_8']);
}
return unpack('q', \danog\MadelineProto\Logger::$BIG_ENDIAN ? strrev($value) : $value)[1];
return unpack('q', \danog\MadelineProto\Magic::$BIG_ENDIAN ? strrev($value) : $value)[1];
}
public function pack_signed_int($value)
@ -96,7 +96,7 @@ trait Tools
}
$res = pack('l', $value);
return \danog\MadelineProto\Logger::$BIG_ENDIAN ? strrev($res) : $res;
return \danog\MadelineProto\Magic::$BIG_ENDIAN ? strrev($res) : $res;
}
public function pack_signed_long($value)
@ -107,7 +107,7 @@ trait Tools
if ($value < -9.223372036854776E+18) {
throw new TL\Exception(sprintf(\danog\MadelineProto\Lang::$current_lang['value_smaller_than_9223372036854775808'], $value));
}
$res = \danog\MadelineProto\Logger::$bigint ? $this->pack_signed_int($value)."\0\0\0\0" : (\danog\MadelineProto\Logger::$BIG_ENDIAN ? strrev(pack('q', $value)) : pack('q', $value));
$res = \danog\MadelineProto\Magic::$bigint ? $this->pack_signed_int($value)."\0\0\0\0" : (\danog\MadelineProto\Magic::$BIG_ENDIAN ? strrev(pack('q', $value)) : pack('q', $value));
return $res;
}
@ -131,7 +131,7 @@ trait Tools
throw new TL\Exception(\danog\MadelineProto\Lang::$current_lang['encode_double_error']);
}
return \danog\MadelineProto\Logger::$BIG_ENDIAN ? strrev($res) : $res;
return \danog\MadelineProto\Magic::$BIG_ENDIAN ? strrev($res) : $res;
}
public function unpack_double($value)
@ -140,6 +140,6 @@ trait Tools
throw new TL\Exception(\danog\MadelineProto\Lang::$current_lang['length_not_8']);
}
return unpack('d', \danog\MadelineProto\Logger::$BIG_ENDIAN ? strrev($value) : $value)[1];
return unpack('d', \danog\MadelineProto\Magic::$BIG_ENDIAN ? strrev($value) : $value)[1];
}
}