当前位置: 首页 > news >正文

做词频云图的网站上海网站建设优化公司

做词频云图的网站,上海网站建设优化公司,电子工程世界注册,wordpress移动支付免费问题背景 最近接手了一个骨灰级的项目#xff0c;然而在项目中遇到了一个普遍的挑战#xff1a;由于公司采用 ELK#xff08;Elasticsearch、Logstash、Kibana#xff09;作为日志收集和分析工具#xff0c;追踪生产问题成为了一大难题。尽管 ELK 提供了强大的日志分析功…问题背景 最近接手了一个骨灰级的项目然而在项目中遇到了一个普遍的挑战由于公司采用 ELKElasticsearch、Logstash、Kibana作为日志收集和分析工具追踪生产问题成为了一大难题。尽管 ELK 提供了强大的日志分析功能但由于项目历史悠久日志输出不规范缺乏唯一标识导致在海量日志中准确定位问题变得异常困难。为了提升生产环境下的问题排查和故障诊断效率迫切需要在项目中引入一种机制能够为每个请求生成唯一的标识符traceId并将其与 ELK 集成以便在日志中准确追踪请求的全链路过程。 系统默认日志格式 elk 对这种格式采集并不太友好所以打算重新写一个日志log类。每一条日志都非常清晰区分 error、info、sql 级别 log排查起来也非常直观。 先看效果 查看application/config.php配置文件第一反应就是这个File到底在哪OK我们直接全局搜索 File.php最终锁定文件路径source/thinkphp/library/think/log/driver/File.php 基于自身业务改造时间比较短哈改写了一个初版简单粗暴就是日志单行展示可以短时间适配业务改造后的代码如下 ?phpnamespace app\common\library;use think\App; use think\Request;class YopLog {protected $config [time_format c ,single false,file_size 2097152,path LOG_PATH,apart_level [],max_files 0,json true,];// 实例化并传入参数public function __construct($config []){if (is_array($config)) {$this-config array_merge($this-config, $config);}}/*** 日志写入接口* access public* param array $log 日志信息* param bool $append 是否追加请求信息* return bool*/public function save(array $log [], $append false){$destination $this-getMasterLogFile();$path dirname($destination);!is_dir($path) mkdir($path, 0755, true);$info [];foreach ($log as $type $val) {foreach ($val as $msg) {if (!is_string($msg)) {if (!$this-config[json]) {$msg var_export($msg, true);}}$info[$type][] $this-config[json] ? $msg : [ . $type . ] . $msg;}if (!$this-config[json] (true $this-config[apart_level] || in_array($type, $this-config[apart_level]))) {// 独立记录的日志级别$filename $this-getApartLevelFile($path, $type);$this-write($info[$type], $filename, true, $append);unset($info[$type]);}}if ($info) {return $this-write($info, $destination, false, $append);}return true;}/*** 获取主日志文件名* access public* return string*/protected function getMasterLogFile(){if ($this-config[single]) {$name is_string($this-config[single]) ? $this-config[single] : single;$destination $this-config[path] . $name . .log;} else {$cli PHP_SAPI cli ? _cli : ;if ($this-config[max_files]) {$filename date(Ymd) . $cli . .log;$files glob($this-config[path] . *.log);try {if (count($files) $this-config[max_files]) {unlink($files[0]);}} catch (\Exception $e) {}} else {$filename date(Ym) . DIRECTORY_SEPARATOR . date(d) . $cli . .log;}$destination $this-config[path] . $filename;}return $destination;}/*** 获取独立日志文件名* access public* param string $path 日志目录* param string $type 日志类型* return string*/protected function getApartLevelFile($path, $type){$cli PHP_SAPI cli ? _cli : ;if ($this-config[single]) {$name is_string($this-config[single]) ? $this-config[single] : single;$name . _ . $type;} elseif ($this-config[max_files]) {$name date(Ymd) . _ . $type . $cli;} else {$name date(d) . _ . $type . $cli;}return $path . DIRECTORY_SEPARATOR . $name . .log;}/*** 日志写入* access protected* param array $message 日志信息* param string $destination 日志文件* param bool $apart 是否独立文件写入* param bool $append 是否追加请求信息* return bool*/protected function write($message, $destination, $apart false, $append false){// 检测日志文件大小超过配置大小则备份日志文件重新生成$this-checkLogSize($destination);// 日志信息封装$info[timestamp] date($this-config[time_format]);if ($this-config[json]) {foreach ($message as $type $msg) {if (is_array($msg)) {for ($i 0; $i count($msg); $i) {$info[$type][$i] $msg[$i] ?? ;}} else {$info[$type] $msg;}}} else {foreach ($message as $type $msg) {$info[$type] is_array($msg) ? implode(\r\n, $msg) : $msg;}}if (PHP_SAPI cli) {$message $this-parseCliLog($info);} else {// 添加调试日志$this-getDebugLog($info, $append, $apart);$message $this-parseLog($info);}return error_log(sprintf(%s %s, date(Y-m-d H:i:s), $message), 3, $destination);}/*** 检查日志文件大小并自动生成备份文件* access protected* param string $destination 日志文件* return void*/protected function checkLogSize($destination){if (is_file($destination) floor($this-config[file_size]) filesize($destination)) {try {rename($destination, dirname($destination) . DIRECTORY_SEPARATOR . time() . - . basename($destination));} catch (\Exception $e) {}}}/*** CLI日志解析* access protected* param array $info 日志信息* return string*/protected function parseCliLog($info){if ($this-config[json]) {$message json_encode($info, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . \r\n;} else {$now $info[timestamp];unset($info[timestamp]);$message implode(\r\n, $info);$message [{$now}] . $message . \r\n;}return $message;}/*** 解析日志* access protected* param array $info 日志信息* return string*/protected function parseLog($info){$request Request::instance();$requestInfo [traceId $_SERVER[traceId] ?? ,ip $request-ip(),method $request-method(),host $request-host(),uri $request-url(),];if ($this-config[json]) {$info $requestInfo $info;return json_encode($info, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . \r\n;}array_unshift($info, ---------------------------------------------------------------\r\n[{$info[timestamp]}] {$requestInfo[ip]} {$requestInfo[method]} {$requestInfo[host]}{$requestInfo[uri]});unset($info[timestamp]);return implode(\r\n, $info) . \r\n;}protected function getDebugLog($info, $append, $apart){if (App::$debug $append) {if ($this-config[json]) {// 获取基本信息$runtime round(microtime(true) - THINK_START_TIME, 10);$reqs $runtime 0 ? number_format(1 / $runtime, 2) : ∞;$memory_use number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2);$info [runtime number_format($runtime, 6) . s,reqs $reqs . req/s,memory $memory_use . kb,file count(get_included_files()),] $info;} elseif (!$apart) {// 增加额外的调试信息$runtime round(microtime(true) - THINK_START_TIME, 10);$reqs $runtime 0 ? number_format(1 / $runtime, 2) : ∞;$memory_use number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2);$time_str [运行时间 . number_format($runtime, 6) . s] [吞吐率 . $reqs . req/s];$memory_str [内存消耗 . $memory_use . kb];$file_load [文件加载 . count(get_included_files()) . ];array_unshift($info, $time_str . $memory_str . $file_load);}}} }探索日志追踪解决方案 1. 生成 traceId 需要一个能够生成唯一 traceId 的方法确保每个请求都有一个唯一的标识符。 2. 存储 traceId 将生成的 traceId 存储在 $_SERVER 中以便在整个请求处理过程中都能够方便地访问到它。 3. 添加到响应头中 在每次请求的响应中都添加 traceId 到响应头中以便客户端收到响应后可以通过 traceId 与请求对应起来。 4. 处理异步请求 对于异步请求需要在发送请求时将 traceId 包含在请求头中以便日志也能够与对应的原始请求进行关联。 解决方案 1. 生成 traceId 在 Tags.php 中的 app_begin 钩子中执行以下操作 ?php return [// 应用开始app_begin [app\\api\\behavior\\TraceId], ];2. 存储 traceId 将生成的 traceId 存储在 $_SERVER 中或者存储在header中。 为了简化获取 traceId 的代码我选择将其存储在 $_SERVER 中。这样只需要通过 $_SERVER[‘traceId’] 就能够轻松获取到 traceId而不需要编写繁琐的获取代码。相比之下如果将 traceId 存储在请求体的 header 中获取代码则需要写成 (Request::instance()-header())[‘traceId’] ?? “”。此外如果系统中存在原生调用需要获取所有的 header 头就需要使用到 getallheaders() 函数。然而getallheaders() 函数只能获取到最初请求打到服务上的所有 header 内容而手动设置的 header 是无法被 getallheaders() 函数获取到的。因此将 traceId 存储在 $_SERVER 中可以更加方便地获取并且不受限于原生调用的影响 3. 添加到响应头中 在响应头中添加 traceId。 ?phpnamespace app\api\behavior;/*** TraceId 行为类** 此行为类用于在 API 请求的上下文中自动注入一个唯一的 traceId 到 HTTP 响应头。* traceId 主要用于链路追踪有助于在日志中跟踪请求的全链路过程* 提升系统问题排查和诊断的效率。*/ class TraceId {/*** 执行行为** return void*/public function run(){// 使用generateTraceId()函数生成一个唯一的traceId值$traceId generateTraceId();// 将生成的唯一traceId值存储在$_SERVER全局变量中$_SERVER[traceId] $traceId;// 设置响应头header(X-Trace-Id: {$traceId});} }4. 处理异步请求 在异步请求中确保在发送请求时将 traceId 包含在请求头中。 发送请求 public function exec_bce($method, $post) {$config new \stdClass();$config-secret dz_mufeng;$sign $this-make_sign($post, $config);$traceId $_SERVER[traceId] ?? ;// 获取数据$content http_build_query($post, , );$header [Content-type:application/x-www-form-urlencoded,Content-length: . strlen($content),traceId: . $traceId];$context[http] [timeout 60,method POST,header implode(\r\n, $header),content $content,];$url config(bce_url)./code.php?method . $method . sign . $sign;log_write(code_exec_context: . json_encode($context), info);$contextStream stream_context_create($context);$res file_get_contents($url, false, $contextStream);log_write(执行返回结果 . $res, info);$res preg_replace(/[\x00-\x1F\x80-\xFF]/, , $res);$res json_decode($res, true);if ($res[result] 0) {return $this-renderError($res[data]);} else {return $this-renderSuccess($res[data]);}}本系统原生代码在接收请求时可直接使用 $_SERVER[‘HTTP_TRACEID’] 获取 traceId。 ?php public function log($params, $type info) {if (!is_string($params)) {$params json_encode($params, 320);}$requestId $_SERVER[traceId] ?? ;$traceId $_SERVER[HTTP_TRACEID] ?? ;!is_dir($this-logPath) mkdir($this-logPath, 0755, true);$requestInfo [[trace_id] empty($traceId) ? $requestId : $traceId,[request_ip] $this-getIp(),[method] $_SERVER[REQUEST_METHOD],[domain] sprintf(%s://%s, $_SERVER[REQUEST_SCHEME], $_SERVER[HTTP_HOST]),[uri] sprintf(%s://%s%s, $_SERVER[REQUEST_SCHEME], $_SERVER[HTTP_HOST], $_SERVER[REQUEST_URI]),[param] $params . \r\n,[trace] (new \Exception)-getTraceAsString()];$println ---------------------------------------------------------------\r\n;$msg sprintf(%s%s [%s] , $println, date(Y-m-d H:i:s), $type);foreach ($requestInfo as $key $value) {$msg . sprintf(%s: %s , $key, $value);}file_put_contents(sprintf(%s/%s_%s,$this-logPath, date(d), api.log), $msg . \r\n, FILE_APPEND); }修改完之后日志中心检索发现日志好多报错发现不规范获取数据索引导致。 这类错误暂时不影响主流程可以屏蔽掉那么 [8] 代表什么他代表错误级别可以针对性屏蔽掉。 详见: Core_d.php 可以在框架对应模块的基类中过滤掉 error_reporting(E_ERROR | E_PARSE); 这段代码是用来设置 PHP 错误报告级别的。在 PHP 中你可以通过修改 error_reporting 指令来控制哪些类型的错误将被报告。在这个例子中error_reporting 被设置为报告四种类型的错误 E_ERROR 严重错误可能会导致脚本终止执行。 E_WARNING 警告不会导致脚本终止执行但可能会表明存在问题。 E_PARSE 语法解析错误通常是由于语法错误而导致的解析失败。 E_NOTICE 提示指出可能会导致问题的非致命性错误。 通过将这些错误类型组合起来这段代码将导致 PHP 报告这四种类型的错误而忽略其它类型的错误。这通常有助于在开发和调试阶段发现潜在的问题但在生产环境中通常会调整为仅报告严重错误如 E_ERROR。 结论 以上解决方案有效地为 ThinkPHP5 的日志添加了 traceId实现了请求的全链路追踪包括异步请求确保请求连贯性从而提高了系统问题排查和诊断的效率。
文章转载自:
http://www.morning.xzqzd.cn.gov.cn.xzqzd.cn
http://www.morning.dgknl.cn.gov.cn.dgknl.cn
http://www.morning.ljhnn.cn.gov.cn.ljhnn.cn
http://www.morning.xctdn.cn.gov.cn.xctdn.cn
http://www.morning.srbl.cn.gov.cn.srbl.cn
http://www.morning.4r5w91.cn.gov.cn.4r5w91.cn
http://www.morning.drmbh.cn.gov.cn.drmbh.cn
http://www.morning.bksbx.cn.gov.cn.bksbx.cn
http://www.morning.rnqnp.cn.gov.cn.rnqnp.cn
http://www.morning.qzsmz.cn.gov.cn.qzsmz.cn
http://www.morning.mmqng.cn.gov.cn.mmqng.cn
http://www.morning.xnltz.cn.gov.cn.xnltz.cn
http://www.morning.hjwkq.cn.gov.cn.hjwkq.cn
http://www.morning.gjssk.cn.gov.cn.gjssk.cn
http://www.morning.gnkbf.cn.gov.cn.gnkbf.cn
http://www.morning.nlrxh.cn.gov.cn.nlrxh.cn
http://www.morning.rkrl.cn.gov.cn.rkrl.cn
http://www.morning.xqgh.cn.gov.cn.xqgh.cn
http://www.morning.yhjlg.cn.gov.cn.yhjlg.cn
http://www.morning.nwqyq.cn.gov.cn.nwqyq.cn
http://www.morning.fykrm.cn.gov.cn.fykrm.cn
http://www.morning.rgdcf.cn.gov.cn.rgdcf.cn
http://www.morning.jqmmf.cn.gov.cn.jqmmf.cn
http://www.morning.kjyqr.cn.gov.cn.kjyqr.cn
http://www.morning.ryxyz.cn.gov.cn.ryxyz.cn
http://www.morning.hflrz.cn.gov.cn.hflrz.cn
http://www.morning.lgnrl.cn.gov.cn.lgnrl.cn
http://www.morning.spwm.cn.gov.cn.spwm.cn
http://www.morning.ckzjl.cn.gov.cn.ckzjl.cn
http://www.morning.nwqyq.cn.gov.cn.nwqyq.cn
http://www.morning.qlrwf.cn.gov.cn.qlrwf.cn
http://www.morning.sphft.cn.gov.cn.sphft.cn
http://www.morning.gqjqf.cn.gov.cn.gqjqf.cn
http://www.morning.yqqgp.cn.gov.cn.yqqgp.cn
http://www.morning.rxzcl.cn.gov.cn.rxzcl.cn
http://www.morning.mqxzh.cn.gov.cn.mqxzh.cn
http://www.morning.tdfyj.cn.gov.cn.tdfyj.cn
http://www.morning.nffwl.cn.gov.cn.nffwl.cn
http://www.morning.saastob.com.gov.cn.saastob.com
http://www.morning.lsnnc.cn.gov.cn.lsnnc.cn
http://www.morning.fglyb.cn.gov.cn.fglyb.cn
http://www.morning.rwbh.cn.gov.cn.rwbh.cn
http://www.morning.xhpnp.cn.gov.cn.xhpnp.cn
http://www.morning.pfjbn.cn.gov.cn.pfjbn.cn
http://www.morning.pkpqh.cn.gov.cn.pkpqh.cn
http://www.morning.dblfl.cn.gov.cn.dblfl.cn
http://www.morning.tbqdm.cn.gov.cn.tbqdm.cn
http://www.morning.gqjqf.cn.gov.cn.gqjqf.cn
http://www.morning.bwfsn.cn.gov.cn.bwfsn.cn
http://www.morning.bjsites.com.gov.cn.bjsites.com
http://www.morning.mgbsp.cn.gov.cn.mgbsp.cn
http://www.morning.jbpodhb.cn.gov.cn.jbpodhb.cn
http://www.morning.jqzns.cn.gov.cn.jqzns.cn
http://www.morning.wftrs.cn.gov.cn.wftrs.cn
http://www.morning.czcbl.cn.gov.cn.czcbl.cn
http://www.morning.gxcit.com.gov.cn.gxcit.com
http://www.morning.zgdnd.cn.gov.cn.zgdnd.cn
http://www.morning.rbnj.cn.gov.cn.rbnj.cn
http://www.morning.kzhgy.cn.gov.cn.kzhgy.cn
http://www.morning.yfddl.cn.gov.cn.yfddl.cn
http://www.morning.bwdnx.cn.gov.cn.bwdnx.cn
http://www.morning.qgcfb.cn.gov.cn.qgcfb.cn
http://www.morning.ryxbz.cn.gov.cn.ryxbz.cn
http://www.morning.mldrd.cn.gov.cn.mldrd.cn
http://www.morning.yuminfo.com.gov.cn.yuminfo.com
http://www.morning.rzczl.cn.gov.cn.rzczl.cn
http://www.morning.wrysm.cn.gov.cn.wrysm.cn
http://www.morning.ymbqr.cn.gov.cn.ymbqr.cn
http://www.morning.dxhnm.cn.gov.cn.dxhnm.cn
http://www.morning.fssjw.cn.gov.cn.fssjw.cn
http://www.morning.srhqm.cn.gov.cn.srhqm.cn
http://www.morning.zhiheliuxue.com.gov.cn.zhiheliuxue.com
http://www.morning.fzqfb.cn.gov.cn.fzqfb.cn
http://www.morning.rxlck.cn.gov.cn.rxlck.cn
http://www.morning.lskyz.cn.gov.cn.lskyz.cn
http://www.morning.cwqpl.cn.gov.cn.cwqpl.cn
http://www.morning.lqpzb.cn.gov.cn.lqpzb.cn
http://www.morning.trnl.cn.gov.cn.trnl.cn
http://www.morning.ghxkm.cn.gov.cn.ghxkm.cn
http://www.morning.sgnjg.cn.gov.cn.sgnjg.cn
http://www.tj-hxxt.cn/news/267072.html

相关文章:

  • 零基础学建网站网站首页网址
  • 鲜花网站开发品牌策划文案
  • 南宁网站建设索q.479185700全球邮企业邮箱
  • 临西网站建设电话wordpress各部分的关系
  • 中国工商建设标准化协会网站wordpress相册列表
  • ppt素材网站建设流程图用wordpress搭建商城
  • 兰考县住房和城乡建设局网站高端网站建设 骆诗
  • 网站建设开发服务费税率做网站买域名
  • 可以做课后作业的网站沈阳男科医院咨询电话
  • 黔南州建设局门户网站xampp 开发网站
  • 2008 iis 添加网站专业外贸网站开发
  • 汽车制造网站建设东莞网站建设报价
  • 微网站有哪些网页制作培训多少钱一天
  • 物业管理系统和物业管理软件淘宝关键词优化技巧教程
  • 网站免费永久人防网站建设
  • 免费一键自助建站官网公司网站内容
  • ps制作网站首页教程设计签名 免费 名字
  • 建站免费建站平台深圳企业管理培训查询
  • 广州免费建站找哪家金溪县建设局网站
  • 重庆网站建设模板制作学做网站教程
  • 网站可以用PS设计吗营销型网站建设公司排名
  • 网站做会员用什么源码建下载网站
  • 网站的设计思路范文做网站的具体需求
  • 巅云建站给自己的网站做关键词流程
  • 网站建设 微信小程序网页设计师证书怎么考?
  • wordpress博客主题哪个好东莞网站排名优化报价
  • 淘宝客网站怎么做的人少了WordPress网络功能
  • 房屋租赁网站开发意义荆州网站建设公司
  • 网站收费怎么做旅游网站的设计与实现开题报告
  • 网站目录扫描自己做购物网站