SugarCRM6.5支持使用Elasticsearch记录日志

作者:James Zhu ([email protected])

创建日期:2018-09-03

修改步骤

  1. composer.json文件中引入 elasticsearch-php

    {
        "require": {
            "elasticsearch/elasticsearch": "~6.0"
        }
    }
    

    注意:elasticsearch v6 要求 PHP7及以上 版本,如若不是请自行修改成合适的版本。

  2. 使用 composer 安装 elasticsearch-php

    curl -s http://getcomposer.org/installer | php
    php composer.phar install --no-dev
    
  3. 修改config_override.php文件,加入ESLogger相关配置:

    $sugar_config['logger']['es']['enable'] = true;
    $sugar_config['logger']['es']['host'] = 'localhost:9200';
    // $sugar_config['logger']['es']['index'] = 'sugarcrm';
    $sugar_config['logger']['es']['suffix'] = '%Y%m%d';
    
  4. 新建custom/include/SugarLogger/ESLogger.php文件:

    require_once('include/SugarLogger/LoggerTemplate.php');
    require_once('vendor/autoload.php');
    
    class ESLogger implements LoggerTemplate {
    
        private $client;
        private $index;
        private $data;
    
        /**
         * Constructor
         *
         * Reads the config file for logger settings
         */
        public function __construct() {
            // load configuration
            $config = SugarConfig::getInstance();
            // if ESLogger enabled
            if(!$config->get('logger.es.enable')) {
                return false;
            }
            // get es host
            $eshost = $config->get('logger.es.host');
            if(empty($eshost)) {
                throw new InvalidArgumentException('[logger.es.host] not defined', 1);
            }
            // init es client
            $this->client = Elasticsearch\ClientBuilder::create()
                ->setHosts([$eshost])
                ->setRetries(0)
                ->build();
            // get index from config
            $this->index = $config->get('logger.es.index');
            // default index
            !empty($this->index) || $this->index = 'sugarcrm';
            // get suffix from config
            $suffix = $config->get('logger.es.suffix');
            if($suffix) {
                $this->index .= '-'.date(str_replace('%', '', $suffix));
            }
            // set ESLogger as default logger
            LoggerManager::setLogger('default', __CLASS__);
            unset($config);
        }
    
        /**
         * @see LoggerTemplate::log()
         */
        public function log($level, $message) {
            global $current_user;
            // change to a string if there is just one entry
            if(is_array($message) && count($message) == 1) {
                $message = array_shift($message);
            }
            // change to a human-readable array output if it's any other array
            if(is_array($message)) {
                $message = print_r($message, true);
            }
            list($msec, $sec) = explode(' ', microtime());
            $this->data[] = array(
                'level' => $level,
                'timestamp' => gmdate('Y-m-d\TH:i:s.'.round($msec * 1000).'\Z', $sec),
                'message' => $message,
                'user' => ($current_user->id ? $current_user->id : 0),
            );
            // bulk indexing every hundred logs
            if(count($this->data) >= 100) {
                $this->bulk();
            }
        }
    
        /**
         * @internal bulk indexing
         */
        private function bulk() {
            if(count($this->data) == 0) return false;
            $params = array();
            foreach($this->data as $data) {
                $params['body'][] = [
                    'index' => [
                        '_index' => $this->index,
                        '_type' => $data['level'],
                    ]
                ];
                $params['body'][] = [
                    'timestamp' => $data['timestamp'],
                    'message' => $data['message'],
                    'user' => $data['user'],
                ];
            }
            $responses = $this->client->bulk($params);
            $this->data = array();
        }
    
        /**
         * Destructor
         *
         * bulk indexing when script exited
         */
        public function __destruct() {
            $this->bulk();
            unset($this->client);
        }
    
    }
    
  5. 至此ESLogger就已经配置完成了。

注解

因为ESLoggerSugarLogger之后加载,因此无需改动其它代码,ESLogger就已经作为默认日志处理类。

这个类会暂存100条日志记录后集中发送,或者在程序结束后集中发送。

相比文件日志的存储方式,ES在搜索、分类查找方面有着天生的优势,非常适合作为日志收集。配合Kibana使用起来非常方便。

kibana

results matching ""

    No results matching ""