<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Apache SkyWalking – Nginx</title>
    <link>/tags/nginx/</link>
    <description>Recent content in Nginx on Apache SkyWalking</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Thu, 04 Jan 2024 00:00:00 +0000</lastBuildDate>
    
	  <atom:link href="/tags/nginx/feed.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Zh: SkyWalking 如何支持 ZIO 等 Scala Effect Runtime</title>
      <link>/zh/2024-01-04-skywalking-for-scala-effect-runtime/</link>
      <pubDate>Thu, 04 Jan 2024 00:00:00 +0000</pubDate>
      <guid>/zh/2024-01-04-skywalking-for-scala-effect-runtime/</guid>
      <description>
        
        
        &lt;h2 id=&#34;背景介绍&#34;&gt;背景介绍&lt;/h2&gt;
&lt;p&gt;在 Scala 中，纯函数式中主要使用 Fiber，而不是线程，诸如 &lt;a href=&#34;https://github.com/typelevel/cats-effect&#34;&gt;Cats-Effect&lt;/a&gt;、&lt;a href=&#34;https://github.com/zio/zio&#34;&gt;ZIO&lt;/a&gt; 等 Effect 框架。
您可以将 Fiber 视为轻量级线程，它是一种并发模型，由框架本身掌控控制权，从而消除了上下文切换的开销。
基于这些 Effect 框架开发的 HTTP、gRCP、GraphQL 库而开发的应用，我们一般称为 &lt;strong&gt;纯函数式应用程序&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;我们以 ZIO 为切入点， 演示 SkyWalking Scala 如何支持 Effect 生态。&lt;/p&gt;
&lt;h2 id=&#34;zio-trace&#34;&gt;ZIO Trace&lt;/h2&gt;
&lt;p&gt;首先，我们想要实现 Fiber 上下文传递，而不是监控 Fiber 本身。对于一个大型应用来说，可能存在成千上万个 Fiber，监控 Fiber 本身的意义不大。&lt;/p&gt;
&lt;p&gt;虽然 Fiber 的 Span 是在活跃时才会创建，但难免会有目前遗漏的场景，所以提供了一个配置 &lt;code&gt;plugin.ziov2.ignore_fiber_regexes&lt;/code&gt;。
它将使用正则去匹配 Fiber location，匹配上的 Fiber 将不会创建 Span。&lt;/p&gt;
&lt;p&gt;Fiber Span的信息如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;FiberSpan.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;下面是我们使用本 ZIO 插件，和一些官方插件（hikaricp、jdbc、pulsar）完成的 Trace：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;skywalking-scala-zio.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;分析&#34;&gt;分析&lt;/h2&gt;
&lt;p&gt;在 ZIO 中，Fiber可以有两种方式被调度，它们都是 &lt;code&gt;zio.Executor&lt;/code&gt; 的子类。当然您也可以使用自己的线程池，这样也需被 ZIO 包装，其实就类似下面的 &lt;code&gt;blockingExecutor&lt;/code&gt;。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scala&#34; data-lang=&#34;scala&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;abstract&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;Executor&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;extends&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;ExecutorPlatformSpecific&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  self &lt;span style=&#34;color:#cf222e&#34;&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#cf222e&#34;&gt;def&lt;/span&gt; submit&lt;span style=&#34;color:#0550ae&#34;&gt;(&lt;/span&gt;runnable&lt;span style=&#34;color:#cf222e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;Runnable&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;)(&lt;/span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;implicit&lt;/span&gt; unsafe&lt;span style=&#34;color:#cf222e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;Unsafe&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;Boolean&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;一种是系统默认线程池 &lt;code&gt;defaultExecutor&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scala&#34; data-lang=&#34;scala&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;private&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;zio&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;trait&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;RuntimePlatformSpecific&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#cf222e&#34;&gt;final&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;val&lt;/span&gt; defaultExecutor&lt;span style=&#34;color:#cf222e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;Executor&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#1f2328&#34;&gt;Executor&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;makeDefault&lt;span style=&#34;color:#0550ae&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;另一种是专用于阻塞 IO 的线程池 &lt;code&gt;blockingExecutor&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scala&#34; data-lang=&#34;scala&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;private&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;zio&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;trait&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;RuntimePlatformSpecific&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#cf222e&#34;&gt;final&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;val&lt;/span&gt; defaultBlockingExecutor&lt;span style=&#34;color:#cf222e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;Executor&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#1f2328&#34;&gt;Blocking&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;blockingExecutor
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;默认线程池-defaultexecutor&#34;&gt;默认线程池 &lt;code&gt;defaultExecutor&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;对于 &lt;code&gt;defaultExecutor&lt;/code&gt;，其本身是很复杂的，但它就是一个 ZIO 的 Fiber 调度（执行）器：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scala&#34; data-lang=&#34;scala&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#57606a&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#57606a&#34;&gt; * A `ZScheduler` is an `Executor` that is optimized for running ZIO
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#57606a&#34;&gt; * applications. Inspired by &amp;#34;Making the Tokio Scheduler 10X Faster&amp;#34; by Carl
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#57606a&#34;&gt; * Lerche. [[https://tokio.rs/blog/2019-10-scheduler]]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#57606a&#34;&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;final&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;ZScheduler&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;extends&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;Executor&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;由于它们都是 &lt;code&gt;zio.Executor&lt;/code&gt; 的子类，我们只需要对其及其子类进行增强：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scala&#34; data-lang=&#34;scala&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;final&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;val&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;ENHANCE_CLASS&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;LogicalMatchOperation&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;or&lt;span style=&#34;color:#0550ae&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#1f2328&#34;&gt;HierarchyMatch&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;byHierarchyMatch&lt;span style=&#34;color:#0550ae&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;zio.Executor&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#1f2328&#34;&gt;MultiClassNameMatch&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;byMultiClassMatch&lt;span style=&#34;color:#0550ae&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;zio.Executor&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;它们都是线程池，我们只需要在 &lt;code&gt;zio.Executor&lt;/code&gt; 的 &lt;code&gt;submit&lt;/code&gt; 方法上进行类似 &lt;code&gt;ThreadPoolExecutor&lt;/code&gt; 上下文捕获的操作，可以参考 &lt;a href=&#34;https://github.com/apache/skywalking-java/blob/main/apm-sniffer/bootstrap-plugins/jdk-threadpool-plugin/src/main/java/org/apache/skywalking/apm/plugin/ThreadPoolSubmitMethodInterceptor.java&#34;&gt;jdk-threadpool-plugin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这里需要注意，因为 Fiber 也是一种 &lt;code&gt;Runnable&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scala&#34; data-lang=&#34;scala&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;private&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;zio&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;trait&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;FiberRunnable&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;extends&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;Runnable&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#cf222e&#34;&gt;def&lt;/span&gt; location&lt;span style=&#34;color:#cf222e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;Trace&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#cf222e&#34;&gt;def&lt;/span&gt; run&lt;span style=&#34;color:#0550ae&#34;&gt;(&lt;/span&gt;depth&lt;span style=&#34;color:#cf222e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;Int&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;Unit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/bitlap/skywalking-scala/blob/master/plugins/zio-v2x-plugin/src/main/scala/org/bitlap/skywalking/apm/plugin/zio/v2x/define/ZioExecutorInstrumentation.scala&#34;&gt;zio-v2x-plugin&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;阻塞线程池-blockingexecutor&#34;&gt;阻塞线程池 &lt;code&gt;blockingExecutor&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;对于 &lt;code&gt;blockingExecutor&lt;/code&gt;，其实它只是对 Java 线程池进行了一个包装：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scala&#34; data-lang=&#34;scala&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;object&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;Blocking&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#cf222e&#34;&gt;val&lt;/span&gt; blockingExecutor&lt;span style=&#34;color:#cf222e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;zio.Executor&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    zio&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;Executor&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;fromThreadPoolExecutor &lt;span style=&#34;color:#0550ae&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#cf222e&#34;&gt;val&lt;/span&gt; corePoolSize  &lt;span style=&#34;color:#cf222e&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#cf222e&#34;&gt;val&lt;/span&gt; maxPoolSize   &lt;span style=&#34;color:#cf222e&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;Int&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;MaxValue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#cf222e&#34;&gt;val&lt;/span&gt; keepAliveTime &lt;span style=&#34;color:#cf222e&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;60000L&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#cf222e&#34;&gt;val&lt;/span&gt; timeUnit      &lt;span style=&#34;color:#cf222e&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;TimeUnit&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;MILLISECONDS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#cf222e&#34;&gt;val&lt;/span&gt; workQueue     &lt;span style=&#34;color:#cf222e&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;SynchronousQueue&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;Runnable&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;]()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#cf222e&#34;&gt;val&lt;/span&gt; threadFactory &lt;span style=&#34;color:#cf222e&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;NamedThreadFactory&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;zio-default-blocking&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#cf222e&#34;&gt;val&lt;/span&gt; threadPool &lt;span style=&#34;color:#cf222e&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;ThreadPoolExecutor&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        corePoolSize&lt;span style=&#34;color:#0550ae&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        maxPoolSize&lt;span style=&#34;color:#0550ae&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        keepAliveTime&lt;span style=&#34;color:#0550ae&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        timeUnit&lt;span style=&#34;color:#0550ae&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        workQueue&lt;span style=&#34;color:#0550ae&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        threadFactory
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#0550ae&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      threadPool
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#0550ae&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;由于其本身是对 &lt;code&gt;ThreadPoolExecutor&lt;/code&gt; 的封装，所以，当我们已经实现了 &lt;code&gt;zio.Executor &lt;/code&gt;的增强后，只需要使用官方 &lt;code&gt;jdk-threadpool-plugin&lt;/code&gt; 插件即可。
这里我们还想要对代码进行定制修改和复用，所以重新使用 Scala 实现了一个 &lt;a href=&#34;https://github.com/bitlap/skywalking-scala/blob/master/plugins/executors-plugin/src/main/scala/org/bitlap/skywalking/apm/plugin/executor/define/ThreadPoolExecutorInstrumentation.scala&#34;&gt;executors-plugin&lt;/a&gt; 插件。&lt;/p&gt;
&lt;h2 id=&#34;串连-fiber-上下文&#34;&gt;串连 Fiber 上下文&lt;/h2&gt;
&lt;p&gt;最后，上面谈到过，Fiber 也是一种 &lt;code&gt;Runnable&lt;/code&gt;，因此还需要对 &lt;code&gt;zio.internal.FiberRunnable&lt;/code&gt; 进行增强。大致分为两点，其实与 &lt;code&gt;jdk-threading-plugin&lt;/code&gt; 是一样的。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;每次创建 &lt;code&gt;zio.internal.FiberRunnable&lt;/code&gt; 实例时，都需要保存 &lt;strong&gt;现场&lt;/strong&gt;，即构造函数增强。&lt;/li&gt;
&lt;li&gt;每次运行时创建一个过渡的 Span，将当前线程上下文与之前保存在构造函数中的上下文进行关联。Fiber 可能被不同线程执行，所以这是必须的。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/bitlap/skywalking-scala/blob/master/plugins/zio-v2x-plugin/src/main/scala/org/bitlap/skywalking/apm/plugin/zio/v2x/define/ZioFiberRuntimeInstrumentation.scala&#34;&gt;zio-v2x-plugin&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;说明&#34;&gt;说明&lt;/h2&gt;
&lt;p&gt;当我们完成了对 ZIO Fiber 的上下文传播处理后，任意基于 ZIO 的应用层框架都可以按照普通的 Java 插件思路去开发。
我们只需要找到一个全局切入点，这个切入点应该是每个请求都会调用的方法，然后对这个方法进行增强。&lt;/p&gt;
&lt;p&gt;要想激活插件，只需要在 Release Notes 下载&lt;a href=&#34;https://github.com/bitlap/skywalking-scala/releases/tag/v0.2.0-beta1&#34;&gt;插件&lt;/a&gt;，放到您的 &lt;code&gt;skywalking-agent/plugins&lt;/code&gt; 目录，重新启动服务即可。&lt;/p&gt;
&lt;p&gt;如果您的项目使用 sbt assembly 打包，您可以参考这个 &lt;a href=&#34;https://github.com/bitlap/skywalking-scala/tree/master/scenarios&#34;&gt;示例&lt;/a&gt;。该项目使用了下列技术栈：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scala&#34; data-lang=&#34;scala&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    libraryDependencies &lt;span style=&#34;color:#0550ae&#34;&gt;++=&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;Seq&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;io.d11&amp;#34;&lt;/span&gt;               &lt;span style=&#34;color:#0550ae&#34;&gt;%%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;zhttp&amp;#34;&lt;/span&gt;                &lt;span style=&#34;color:#0550ae&#34;&gt;%&lt;/span&gt; zioHttp2Version&lt;span style=&#34;color:#0550ae&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;dev.zio&amp;#34;&lt;/span&gt;              &lt;span style=&#34;color:#0550ae&#34;&gt;%%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;zio&amp;#34;&lt;/span&gt;                  &lt;span style=&#34;color:#0550ae&#34;&gt;%&lt;/span&gt; zioVersion&lt;span style=&#34;color:#0550ae&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;io.grpc&amp;#34;&lt;/span&gt;               &lt;span style=&#34;color:#0550ae&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;grpc-netty&amp;#34;&lt;/span&gt;           &lt;span style=&#34;color:#0550ae&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;1.50.1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;com.thesamet.scalapb&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;%%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;scalapb-runtime-grpc&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;%&lt;/span&gt; scalapb&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;compiler&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;Version&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;scalapbVersion
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#0550ae&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;++&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;Seq&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;dev.profunktor&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;%%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;redis4cats-effects&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#0550ae&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;1.3.0&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;dev.profunktor&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;%%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;redis4cats-log4cats&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;1.3.0&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;dev.profunktor&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;%%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;redis4cats-streams&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#0550ae&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;1.3.0&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;org.typelevel&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#0550ae&#34;&gt;%%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;log4cats-slf4j&amp;#34;&lt;/span&gt;      &lt;span style=&#34;color:#0550ae&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;2.5.0&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;dev.zio&amp;#34;&lt;/span&gt;        &lt;span style=&#34;color:#0550ae&#34;&gt;%%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;zio-interop-cats&amp;#34;&lt;/span&gt;    &lt;span style=&#34;color:#0550ae&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;23.0.03&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;ch.qos.logback&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#0550ae&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;logback-classic&amp;#34;&lt;/span&gt;     &lt;span style=&#34;color:#0550ae&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;1.2.11&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;dev.zio&amp;#34;&lt;/span&gt;        &lt;span style=&#34;color:#0550ae&#34;&gt;%%&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;zio-cache&amp;#34;&lt;/span&gt;           &lt;span style=&#34;color:#0550ae&#34;&gt;%&lt;/span&gt; zioCacheVersion
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#0550ae&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
      </description>
    </item>
    
    <item>
      <title>Blog: Monitoring Nginx with SkyWalking</title>
      <link>/blog/2023-12-23-monitoring-nginx-by-skywalking/</link>
      <pubDate>Sat, 23 Dec 2023 00:00:00 +0000</pubDate>
      <guid>/blog/2023-12-23-monitoring-nginx-by-skywalking/</guid>
      <description>
        
        
        &lt;h2 id=&#34;background&#34;&gt;Background&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://skywalking.apache.org/&#34;&gt;Apache SkyWalking&lt;/a&gt; is an open-source application performance management system that helps users collect and aggregate logs, traces, metrics, and events, and display them on the UI.&lt;/p&gt;
&lt;p&gt;In order to achieve monitoring capabilities for Nginx, we have introduced the Nginx monitoring dashboard in SkyWalking 9.7,
and this article will demonstrate the use of this monitoring dashboard and introduce the meaning of related metrics.&lt;/p&gt;
&lt;h2 id=&#34;setup-monitoring-dashboard&#34;&gt;Setup Monitoring Dashboard&lt;/h2&gt;
&lt;h3 id=&#34;metric-define-and-collection&#34;&gt;Metric Define and Collection&lt;/h3&gt;
&lt;p&gt;Since &lt;a href=&#34;https://github.com/knyar/nginx-lua-prometheus&#34;&gt;nginx-lua-prometheus&lt;/a&gt; is used to define and expose metrics,
we need to install &lt;a href=&#34;https://github.com/openresty/lua-nginx-module&#34;&gt;lua_nginx_module&lt;/a&gt; for Nginx, or use &lt;a href=&#34;https://openresty.org&#34;&gt;OpenResty&lt;/a&gt; directly.&lt;/p&gt;
&lt;p&gt;In the following example, we define four metrics via nginx-lua-prometheus and expose the metrics interface via nginx ip:9145/metrics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;histogram: nginx_http_latency，monitoring http latency&lt;/li&gt;
&lt;li&gt;gauge: nginx_http_connections，monitoring nginx http connections&lt;/li&gt;
&lt;li&gt;counter: nginx_http_size_bytes，monitoring http size of request and response&lt;/li&gt;
&lt;li&gt;counter: nginx_http_requests_total，monitoring total http request numbers&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;http {
    log_format  main  &amp;#39;$remote_addr - $remote_user [$time_local] &amp;#34;$request&amp;#34; &amp;#39;
                      &amp;#39;$status $body_bytes_sent &amp;#34;$http_referer&amp;#34; &amp;#39;
                      &amp;#39;&amp;#34;$http_user_agent&amp;#34; &amp;#34;$http_x_forwarded_for&amp;#34;&amp;#39;;

    access_log  /var/log/nginx/access.log  main;

    lua_shared_dict prometheus_metrics 10M;
    # lua_package_path &amp;#34;/path/to/nginx-lua-prometheus/?.lua;;&amp;#34;;

    init_worker_by_lua_block {
      prometheus = require(&amp;#34;prometheus&amp;#34;).init(&amp;#34;prometheus_metrics&amp;#34;)

      metric_bytes = prometheus:counter(
        &amp;#34;nginx_http_size_bytes&amp;#34;, &amp;#34;Total size of HTTP&amp;#34;, {&amp;#34;type&amp;#34;, &amp;#34;route&amp;#34;})
      metric_requests = prometheus:counter(
        &amp;#34;nginx_http_requests_total&amp;#34;, &amp;#34;Number of HTTP requests&amp;#34;, {&amp;#34;status&amp;#34;, &amp;#34;route&amp;#34;})
      metric_latency = prometheus:histogram(
        &amp;#34;nginx_http_latency&amp;#34;, &amp;#34;HTTP request latency&amp;#34;, {&amp;#34;route&amp;#34;})
      metric_connections = prometheus:gauge(
        &amp;#34;nginx_http_connections&amp;#34;, &amp;#34;Number of HTTP connections&amp;#34;, {&amp;#34;state&amp;#34;})
    }

    server {
        listen 8080;

        location /test {
          default_type application/json;
          return 200  &amp;#39;{&amp;#34;code&amp;#34;: 200, &amp;#34;message&amp;#34;: &amp;#34;success&amp;#34;}&amp;#39;;

          log_by_lua_block {
            metric_bytes:inc(tonumber(ngx.var.request_length), {&amp;#34;request&amp;#34;, &amp;#34;/test/**&amp;#34;})
            metric_bytes:inc(tonumber(ngx.var.bytes_send), {&amp;#34;response&amp;#34;, &amp;#34;/test/**&amp;#34;})
            metric_requests:inc(1, {ngx.var.status, &amp;#34;/test/**&amp;#34;})
            metric_latency:observe(tonumber(ngx.var.request_time), {&amp;#34;/test/**&amp;#34;})
          }
        }
    }

    server {
      listen 9145;
      location /metrics {
        content_by_lua_block {
          metric_connections:set(ngx.var.connections_reading, {&amp;#34;reading&amp;#34;})
          metric_connections:set(ngx.var.connections_waiting, {&amp;#34;waiting&amp;#34;})
          metric_connections:set(ngx.var.connections_writing, {&amp;#34;writing&amp;#34;})
          prometheus:collect()
        }
      }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the above example, we exposed the route-level metrics, and you can also choose to expose the host-level metrics according to the monitoring granularity:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;http {
  log_by_lua_block {
      metric_bytes:inc(tonumber(ngx.var.request_length), {&amp;#34;request&amp;#34;, ngx.var.host})
      metric_bytes:inc(tonumber(ngx.var.bytes_send), {&amp;#34;response&amp;#34;, ngx.var.host})
      metric_requests:inc(1, {ngx.var.status, ngx.var.host})
      metric_latency:observe(tonumber(ngx.var.request_time), {ngx.var.host})
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;or upstream-level metrics：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;upstream backend {
  server ip:port;
}

server {
  
  location /test_upstream {
  
    proxy_pass http://backend;
  
    log_by_lua_block {
      metric_bytes:inc(tonumber(ngx.var.request_length), {&amp;#34;request&amp;#34;, &amp;#34;upstream/backend&amp;#34;})
      metric_bytes:inc(tonumber(ngx.var.bytes_send), {&amp;#34;response&amp;#34;, &amp;#34;upstream/backend&amp;#34;})
      metric_requests:inc(1, {ngx.var.status, &amp;#34;upstream/backend&amp;#34;})
      metric_latency:observe(tonumber(ngx.var.request_time), {&amp;#34;upstream/backend&amp;#34;})
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After defining the metrics, we start nginx and opentelemetry-collector to collect the metrics and send them to the SkyWalking backend for analysis and storage.&lt;/p&gt;
&lt;p&gt;Please ensure that &lt;code&gt;job_name: &#39;nginx-monitoring&#39;&lt;/code&gt;, otherwise the reported data will be ignored by SkyWalking.
If you have multiple Nginx instances, you can distinguish them using the &lt;code&gt;service&lt;/code&gt; and &lt;code&gt;service_instance_id&lt;/code&gt; labels：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;receivers:
  prometheus:
    config:
      scrape_configs:
        - job_name: &amp;#39;nginx-monitoring&amp;#39;
          scrape_interval: 5s
          metrics_path: &amp;#34;/metrics&amp;#34;
          static_configs:
            - targets: [&amp;#39;nginx:9145&amp;#39;]
              labels:
                service: nginx
                service_instance_id: nginx-instance
processors:
  batch:

exporters:
  otlp:
    endpoint: oap:11800
    tls:
      insecure: true
service:
  pipelines:
    metrics:
      receivers:
        - prometheus
      processors:
        - batch
      exporters:
        - otlp
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If everything goes well, you will see the metric data reported by Nginx under the gateway menu of the skywalking-ui:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;nginx-metric.png&#34; alt=&#34;nginx-metric&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;access--error-log-collection&#34;&gt;Access &amp;amp; Error Log Collection&lt;/h3&gt;
&lt;p&gt;SkyWalking Nginx monitoring provides log collection and error log analysis. We can use &lt;a href=&#34;https://fluentbit.io/&#34;&gt;fluent-bit&lt;/a&gt; to collect and report access logs and error logs to SkyWalking for analysis and storage.&lt;/p&gt;
&lt;p&gt;Fluent-bit configuration below defines the log collection directory as &lt;code&gt;/var/log/nginx/&lt;/code&gt;.
The access and error logs will be reported through rest port 12800 of oap after being processed by &lt;code&gt;rewrite_access_log&lt;/code&gt; and &lt;code&gt;rewrite_error_log&lt;/code&gt; functions:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[SERVICE]
    Flush          5
    Daemon         Off
    Log_Level      warn
[INPUT]
    Name           tail
    Tag            access
    Path           /var/log/nginx/access.log
[INPUT]
    Name           tail
    Tag            error
    Path           /var/log/nginx/error.log
[FILTER]
    Name           lua
    Match          access
    Script         fluent-bit-script.lua
    Call           rewrite_access_log
[FILTER]
    Name           lua
    Match          error
    Script         fluent-bit-script.lua
    Call           rewrite_error_log
[OUTPUT]
    Name            stdout
    Match           *
    Format          json
[OUTPUT]
    Name            http
    Match           *
    Host            oap
    Port            12800
    URI             /v3/logs
    Format          json
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the &lt;code&gt;fluent-bit-script.lua&lt;/code&gt;, we use &lt;code&gt;LOG_KIND&lt;/code&gt; tag to distinguish between access logs and error logs.&lt;/p&gt;
&lt;p&gt;To associate with the metrics, please ensure that the values of &lt;code&gt;service&lt;/code&gt; and &lt;code&gt;serviceInstance&lt;/code&gt; are consistent with the metric collection definition in the previous section.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function rewrite_access_log(tag, timestamp, record)
    local newRecord = {}
    newRecord[&amp;#34;layer&amp;#34;] = &amp;#34;NGINX&amp;#34;
    newRecord[&amp;#34;service&amp;#34;] = &amp;#34;nginx::nginx&amp;#34;
    newRecord[&amp;#34;serviceInstance&amp;#34;] = &amp;#34;nginx-instance&amp;#34;
    newRecord[&amp;#34;body&amp;#34;] = { text = { text = record.log } }
    newRecord[&amp;#34;tags&amp;#34;] = { data = {{ key = &amp;#34;LOG_KIND&amp;#34;, value = &amp;#34;NGINX_ACCESS_LOG&amp;#34;}}}
    return 1, timestamp, newRecord
end

function rewrite_error_log(tag, timestamp, record)
    local newRecord = {}
    newRecord[&amp;#34;layer&amp;#34;] = &amp;#34;NGINX&amp;#34;
    newRecord[&amp;#34;service&amp;#34;] = &amp;#34;nginx::nginx&amp;#34;
    newRecord[&amp;#34;serviceInstance&amp;#34;] = &amp;#34;nginx-instance&amp;#34;
    newRecord[&amp;#34;body&amp;#34;] = { text = { text = record.log } }
    newRecord[&amp;#34;tags&amp;#34;] = { data = {{ key = &amp;#34;LOG_KIND&amp;#34;, value = &amp;#34;NGINX_ERROR_LOG&amp;#34; }}}
    return 1, timestamp, newRecord
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After starting fluent-it, we can see the collected log information in the Log tab of the monitoring panel：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;nginx-log.png&#34; alt=&#34;nginx-log&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;meaning-of-metrics&#34;&gt;Meaning of Metrics&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Metric Name&lt;/th&gt;
          &lt;th&gt;Unit&lt;/th&gt;
          &lt;th&gt;Description&lt;/th&gt;
          &lt;th&gt;Data Source&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;HTTP Request Trend&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;The increment rate of HTTP requests&lt;/td&gt;
          &lt;td&gt;nginx-lua-prometheus&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HTTP Latency&lt;/td&gt;
          &lt;td&gt;ms&lt;/td&gt;
          &lt;td&gt;The increment rate of the latency of HTTP requests&lt;/td&gt;
          &lt;td&gt;nginx-lua-prometheus&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HTTP Bandwidth&lt;/td&gt;
          &lt;td&gt;KB&lt;/td&gt;
          &lt;td&gt;The increment rate of the bandwidth of HTTP requests&lt;/td&gt;
          &lt;td&gt;nginx-lua-prometheus&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HTTP Connections&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;The avg number of the connections&lt;/td&gt;
          &lt;td&gt;nginx-lua-prometheus&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HTTP Status Trend&lt;/td&gt;
          &lt;td&gt;%&lt;/td&gt;
          &lt;td&gt;The increment rate of the status of HTTP requests&lt;/td&gt;
          &lt;td&gt;nginx-lua-prometheus&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HTTP Status 4xx Percent&lt;/td&gt;
          &lt;td&gt;%&lt;/td&gt;
          &lt;td&gt;The percentage of 4xx status of HTTP requests&lt;/td&gt;
          &lt;td&gt;nginx-lua-prometheus&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HTTP Status 5xx Percent&lt;/td&gt;
          &lt;td&gt;%&lt;/td&gt;
          &lt;td&gt;The percentage of 4xx status of HTTP requests&lt;/td&gt;
          &lt;td&gt;nginx-lua-prometheus&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Error Log Count&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;The count of log level of nginx error.log&lt;/td&gt;
          &lt;td&gt;fluent-bit&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;references&#34;&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/knyar/nginx-lua-prometheus&#34;&gt;nginx-lua-prometheus&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.fluentbit.io/manual/pipeline/filters/lua&#34;&gt;fluent-bit-lua-filter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skywalking.apache.org/docs/main/next/en/setup/backend/backend-apisix-monitoring&#34;&gt;skywalking-apisix-monitoring&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 使用 SkyWalking 监控 Nginx</title>
      <link>/zh/2023-12-23-monitoring-nginx-by-skywalking/</link>
      <pubDate>Sat, 23 Dec 2023 00:00:00 +0000</pubDate>
      <guid>/zh/2023-12-23-monitoring-nginx-by-skywalking/</guid>
      <description>
        
        
        &lt;h2 id=&#34;背景介绍&#34;&gt;背景介绍&lt;/h2&gt;
&lt;p&gt;在前面的 Blog &lt;a href=&#34;https://skywalking.apache.org/zh/2023-10-29-collect-and-analyse-nginx-accesslog-by-lal/&#34;&gt;使用 LAL 收集并分析 Nginx access log&lt;/a&gt; 中，我们以 Nginx access log 为切入点，
演示了 SkyWalking LAL 的日志分析能力。&lt;/p&gt;
&lt;p&gt;为了实现对 Nginx 更全面的监控能力，我们在 SkyWalking 9.7 中引入了 Nginx 监控面板，本文将演示该监控面板的使用，并介绍相关指标的含义。&lt;/p&gt;
&lt;h2 id=&#34;监控面板接入&#34;&gt;监控面板接入&lt;/h2&gt;
&lt;h3 id=&#34;metric-定义与采集&#34;&gt;Metric 定义与采集&lt;/h3&gt;
&lt;p&gt;由于使用了 &lt;a href=&#34;https://github.com/knyar/nginx-lua-prometheus&#34;&gt;nginx-lua-prometheus&lt;/a&gt; 来定义及暴露指标，
我们需要为 Nginx 安装 &lt;a href=&#34;https://github.com/openresty/lua-nginx-module&#34;&gt;lua_nginx_module&lt;/a&gt;， 或者直接使用&lt;a href=&#34;https://openresty.org&#34;&gt;OpenResty&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;下面的例子中，我们通过 nginx-lua-prometheus 定义了四个指标，并通过 ip:9145/metrics 暴露指标接口：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;histogram: nginx_http_latency，监控 http 延时&lt;/li&gt;
&lt;li&gt;gauge: nginx_http_connections，监控 http 连接数&lt;/li&gt;
&lt;li&gt;counter: nginx_http_size_bytes，监控 http 请求和响应大小&lt;/li&gt;
&lt;li&gt;counter: nginx_http_requests_total，监控 http 请求次数&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;http {
    log_format  main  &amp;#39;$remote_addr - $remote_user [$time_local] &amp;#34;$request&amp;#34; &amp;#39;
                      &amp;#39;$status $body_bytes_sent &amp;#34;$http_referer&amp;#34; &amp;#39;
                      &amp;#39;&amp;#34;$http_user_agent&amp;#34; &amp;#34;$http_x_forwarded_for&amp;#34;&amp;#39;;

    access_log  /var/log/nginx/access.log  main;

    lua_shared_dict prometheus_metrics 10M;
    # lua_package_path &amp;#34;/path/to/nginx-lua-prometheus/?.lua;;&amp;#34;;

    init_worker_by_lua_block {
      prometheus = require(&amp;#34;prometheus&amp;#34;).init(&amp;#34;prometheus_metrics&amp;#34;)

      metric_bytes = prometheus:counter(
        &amp;#34;nginx_http_size_bytes&amp;#34;, &amp;#34;Total size of HTTP&amp;#34;, {&amp;#34;type&amp;#34;, &amp;#34;route&amp;#34;})
      metric_requests = prometheus:counter(
        &amp;#34;nginx_http_requests_total&amp;#34;, &amp;#34;Number of HTTP requests&amp;#34;, {&amp;#34;status&amp;#34;, &amp;#34;route&amp;#34;})
      metric_latency = prometheus:histogram(
        &amp;#34;nginx_http_latency&amp;#34;, &amp;#34;HTTP request latency&amp;#34;, {&amp;#34;route&amp;#34;})
      metric_connections = prometheus:gauge(
        &amp;#34;nginx_http_connections&amp;#34;, &amp;#34;Number of HTTP connections&amp;#34;, {&amp;#34;state&amp;#34;})
    }

    server {
        listen 8080;

        location /test {
          default_type application/json;
          return 200  &amp;#39;{&amp;#34;code&amp;#34;: 200, &amp;#34;message&amp;#34;: &amp;#34;success&amp;#34;}&amp;#39;;

          log_by_lua_block {
            metric_bytes:inc(tonumber(ngx.var.request_length), {&amp;#34;request&amp;#34;, &amp;#34;/test/**&amp;#34;})
            metric_bytes:inc(tonumber(ngx.var.bytes_send), {&amp;#34;response&amp;#34;, &amp;#34;/test/**&amp;#34;})
            metric_requests:inc(1, {ngx.var.status, &amp;#34;/test/**&amp;#34;})
            metric_latency:observe(tonumber(ngx.var.request_time), {&amp;#34;/test/**&amp;#34;})
          }
        }
    }

    server {
      listen 9145;
      location /metrics {
        content_by_lua_block {
          metric_connections:set(ngx.var.connections_reading, {&amp;#34;reading&amp;#34;})
          metric_connections:set(ngx.var.connections_waiting, {&amp;#34;waiting&amp;#34;})
          metric_connections:set(ngx.var.connections_writing, {&amp;#34;writing&amp;#34;})
          prometheus:collect()
        }
      }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的例子中，我们暴露了 route 级别的指标，你也可以根据监控粒度的需要，选择暴露 host 指标：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;http {
  log_by_lua_block {
      metric_bytes:inc(tonumber(ngx.var.request_length), {&amp;#34;request&amp;#34;, ngx.var.host})
      metric_bytes:inc(tonumber(ngx.var.bytes_send), {&amp;#34;response&amp;#34;, ngx.var.host})
      metric_requests:inc(1, {ngx.var.status, ngx.var.host})
      metric_latency:observe(tonumber(ngx.var.request_time), {ngx.var.host})
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;或者 upstream 指标：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;upstream backend {
  server ip:port;
}

server {
  
  location /test_upstream {
  
    proxy_pass http://backend;
  
    log_by_lua_block {
      metric_bytes:inc(tonumber(ngx.var.request_length), {&amp;#34;request&amp;#34;, &amp;#34;upstream/backend&amp;#34;})
      metric_bytes:inc(tonumber(ngx.var.bytes_send), {&amp;#34;response&amp;#34;, &amp;#34;upstream/backend&amp;#34;})
      metric_requests:inc(1, {ngx.var.status, &amp;#34;upstream/backend&amp;#34;})
      metric_latency:observe(tonumber(ngx.var.request_time), {&amp;#34;upstream/backend&amp;#34;})
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;完成指标定义后，我们启动 nginx 和 opentelemetry-collector，将指标采集到 SkyWalking 后端进行分析和存储。&lt;/p&gt;
&lt;p&gt;请确保&lt;code&gt;job_name: &#39;nginx-monitoring&#39;&lt;/code&gt;，否则上报的数据将被 SkyWalking 忽略。如果你有多个 Nginx 实例，你可以通过&lt;code&gt;service&lt;/code&gt;及&lt;code&gt;service_instance_id&lt;/code&gt;这两个 label 进行区分：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;receivers:
  prometheus:
    config:
      scrape_configs:
        - job_name: &amp;#39;nginx-monitoring&amp;#39;
          scrape_interval: 5s
          metrics_path: &amp;#34;/metrics&amp;#34;
          static_configs:
            - targets: [&amp;#39;nginx:9145&amp;#39;]
              labels:
                service: nginx
                service_instance_id: nginx-instance
processors:
  batch:

exporters:
  otlp:
    endpoint: oap:11800
    tls:
      insecure: true
service:
  pipelines:
    metrics:
      receivers:
        - prometheus
      processors:
        - batch
      exporters:
        - otlp
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果一切顺利，你将在 skywalking-ui 的网关菜单下看到 nginx 上报的指标数据：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;nginx-metric.png&#34; alt=&#34;nginx-metric&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;access--error-log-采集&#34;&gt;Access &amp;amp; Error Log 采集&lt;/h3&gt;
&lt;p&gt;SkyWalking Nginx 监控提供了日志采集及错误日志统计功能，我们可以借助 &lt;a href=&#34;https://fluentbit.io/&#34;&gt;fluent-bit&lt;/a&gt; 采集并上报 access log、error log 给 SkyWalking 分析存储。&lt;/p&gt;
&lt;p&gt;下面 fluent-bit 配置定义了日志采集目录为&lt;code&gt;/var/log/nginx/&lt;/code&gt;，access 和 error log 经过 &lt;code&gt;rewrite_access_log&lt;/code&gt; 和 &lt;code&gt;rewrite_error_log&lt;/code&gt; 处理后会通过 oap 12800 端口进行上报：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[SERVICE]
    Flush          5
    Daemon         Off
    Log_Level      warn
[INPUT]
    Name           tail
    Tag            access
    Path           /var/log/nginx/access.log
[INPUT]
    Name           tail
    Tag            error
    Path           /var/log/nginx/error.log
[FILTER]
    Name           lua
    Match          access
    Script         fluent-bit-script.lua
    Call           rewrite_access_log
[FILTER]
    Name           lua
    Match          error
    Script         fluent-bit-script.lua
    Call           rewrite_error_log
[OUTPUT]
    Name            stdout
    Match           *
    Format          json
[OUTPUT]
    Name            http
    Match           *
    Host            oap
    Port            12800
    URI             /v3/logs
    Format          json
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在 fluent-bit-script.lua 中，我们通过 LOG_KIND 来区分 access log 和 error log。&lt;/p&gt;
&lt;p&gt;为了能够关联上文采集的 metric，请确保 service 和 serviceInstance 值与上文中指标采集定义一致。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function rewrite_access_log(tag, timestamp, record)
    local newRecord = {}
    newRecord[&amp;#34;layer&amp;#34;] = &amp;#34;NGINX&amp;#34;
    newRecord[&amp;#34;service&amp;#34;] = &amp;#34;nginx::nginx&amp;#34;
    newRecord[&amp;#34;serviceInstance&amp;#34;] = &amp;#34;nginx-instance&amp;#34;
    newRecord[&amp;#34;body&amp;#34;] = { text = { text = record.log } }
    newRecord[&amp;#34;tags&amp;#34;] = { data = {{ key = &amp;#34;LOG_KIND&amp;#34;, value = &amp;#34;NGINX_ACCESS_LOG&amp;#34;}}}
    return 1, timestamp, newRecord
end

function rewrite_error_log(tag, timestamp, record)
    local newRecord = {}
    newRecord[&amp;#34;layer&amp;#34;] = &amp;#34;NGINX&amp;#34;
    newRecord[&amp;#34;service&amp;#34;] = &amp;#34;nginx::nginx&amp;#34;
    newRecord[&amp;#34;serviceInstance&amp;#34;] = &amp;#34;nginx-instance&amp;#34;
    newRecord[&amp;#34;body&amp;#34;] = { text = { text = record.log } }
    newRecord[&amp;#34;tags&amp;#34;] = { data = {{ key = &amp;#34;LOG_KIND&amp;#34;, value = &amp;#34;NGINX_ERROR_LOG&amp;#34; }}}
    return 1, timestamp, newRecord
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;启动 fluent-it 后，我们便可以在监控面板的 Log tab 看到采集到的日志信息：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;nginx-log.png&#34; alt=&#34;nginx-log&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;面板指标含义&#34;&gt;面板指标含义&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;面板名称&lt;/th&gt;
          &lt;th&gt;单位&lt;/th&gt;
          &lt;th&gt;指标含义&lt;/th&gt;
          &lt;th&gt;数据源&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;HTTP Request Trend&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;每秒钟平均请求数&lt;/td&gt;
          &lt;td&gt;nginx-lua-prometheus&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HTTP Latency&lt;/td&gt;
          &lt;td&gt;ms&lt;/td&gt;
          &lt;td&gt;平均响应延时&lt;/td&gt;
          &lt;td&gt;nginx-lua-prometheus&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HTTP Bandwidth&lt;/td&gt;
          &lt;td&gt;KB&lt;/td&gt;
          &lt;td&gt;请求响应流量&lt;/td&gt;
          &lt;td&gt;nginx-lua-prometheus&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HTTP Connections&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;nginx http 连接数&lt;/td&gt;
          &lt;td&gt;nginx-lua-prometheus&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HTTP Status Trend&lt;/td&gt;
          &lt;td&gt;%&lt;/td&gt;
          &lt;td&gt;每分钟 http 状态码统计&lt;/td&gt;
          &lt;td&gt;nginx-lua-prometheus&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HTTP Status 4xx Percent&lt;/td&gt;
          &lt;td&gt;%&lt;/td&gt;
          &lt;td&gt;4xx状态码比例&lt;/td&gt;
          &lt;td&gt;nginx-lua-prometheus&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HTTP Status 5xx Percent&lt;/td&gt;
          &lt;td&gt;%&lt;/td&gt;
          &lt;td&gt;5xx状态码比例&lt;/td&gt;
          &lt;td&gt;nginx-lua-prometheus&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Error Log Count&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;每分钟错误日志数统计&lt;/td&gt;
          &lt;td&gt;fluent-bit&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;参考文档&#34;&gt;参考文档&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/knyar/nginx-lua-prometheus&#34;&gt;nginx-lua-prometheus&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.fluentbit.io/manual/pipeline/filters/lua&#34;&gt;fluent-bit-lua-filter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skywalking.apache.org/docs/main/next/en/setup/backend/backend-apisix-monitoring&#34;&gt;skywalking-apisix-monitoring&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 使用 LAL 收集并分析 Nginx access log</title>
      <link>/zh/2023-10-29-collect-and-analyse-nginx-accesslog-by-lal/</link>
      <pubDate>Sun, 29 Oct 2023 00:00:00 +0000</pubDate>
      <guid>/zh/2023-10-29-collect-and-analyse-nginx-accesslog-by-lal/</guid>
      <description>
        
        
        &lt;h2 id=&#34;背景介绍&#34;&gt;背景介绍&lt;/h2&gt;
&lt;p&gt;Nginx access log 中包含了丰富的信息，例如：日志时间、状态码、响应时间、body 大小等。通过收集并分析 access log，我们可以实现对 Nginx 中接口状态的监控。&lt;/p&gt;
&lt;p&gt;在本案例中，将由 &lt;a href=&#34;https://fluentbit.io/&#34;&gt;fluent-bit&lt;/a&gt; 收集 access log，并通过 HTTP 将日志信息发送给 SkyWalking OAP Server 进行进一步的分析。&lt;/p&gt;
&lt;h2 id=&#34;环境准备&#34;&gt;环境准备&lt;/h2&gt;
&lt;p&gt;实验需要的 Nginx 及 Fluent-bit 相关配置文件都被上传到了&lt;a href=&#34;https://github.com/weixiang1862/nginx-fluent-bit&#34;&gt;Github&lt;/a&gt;，有需要的读者可以自行 git clone 并通过 docker compose 启动，本文中将介绍配置文件中几个关键点。&lt;/p&gt;
&lt;h3 id=&#34;nginx日志格式配置&#34;&gt;Nginx日志格式配置&lt;/h3&gt;
&lt;p&gt;LAL 目前支持 JSON、YAML 及 REGEX 日志解析，为了方便获取到日志中的指标字段，我们将 Nginx 的日志格式定义为 JSON.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;http {
    ...
    ...

    log_format  main  &amp;#39;{&amp;#34;remote_addr&amp;#34;: &amp;#34;$remote_addr&amp;#34;,&amp;#39;
            &amp;#39;&amp;#34;remote_user&amp;#34;: &amp;#34;$remote_user&amp;#34;,&amp;#39;
            &amp;#39;&amp;#34;request&amp;#34;: &amp;#34;$request&amp;#34;,&amp;#39;
            &amp;#39;&amp;#34;time&amp;#34;: &amp;#34;$time_iso8601&amp;#34;,&amp;#39;
            &amp;#39;&amp;#34;status&amp;#34;: &amp;#34;$status&amp;#34;,&amp;#39;
            &amp;#39;&amp;#34;request_time&amp;#34;:&amp;#34;$request_time&amp;#34;,&amp;#39;
            &amp;#39;&amp;#34;body_bytes_sent&amp;#34;: &amp;#34;$body_bytes_sent&amp;#34;,&amp;#39;
            &amp;#39;&amp;#34;http_referer&amp;#34;: &amp;#34;$http_referer&amp;#34;,&amp;#39;
            &amp;#39;&amp;#34;http_user_agent&amp;#34;: &amp;#34;$http_user_agent&amp;#34;,&amp;#39;
            &amp;#39;&amp;#34;http_x_forwarded_for&amp;#34;: &amp;#34;$http_x_forwarded_for&amp;#34;}&amp;#39;;

    access_log  /var/log/nginx/access.log  main;
    
    ...
    ...
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;fluent-bit-filter&#34;&gt;Fluent bit Filter&lt;/h3&gt;
&lt;p&gt;我们通过 Fluent bit 的 lua filter 进行日志格式的改写，将其调整为 SkyWalking 所需要的格式，record的各个字段含义如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;body：日志内容体&lt;/li&gt;
&lt;li&gt;service：服务名称&lt;/li&gt;
&lt;li&gt;serviceInstance：实例名称&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function rewrite_body(tag, timestamp, record)
    local newRecord = {}
    newRecord[&amp;#34;body&amp;#34;] = { json = { json = record.log } }
    newRecord[&amp;#34;service&amp;#34;] = &amp;#34;nginx::nginx&amp;#34;
    newRecord[&amp;#34;serviceInstance&amp;#34;] = &amp;#34;localhost&amp;#34;
    return 1, timestamp, newRecord
end
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;oap-日志分析&#34;&gt;OAP 日志分析&lt;/h2&gt;
&lt;h3 id=&#34;lal定义&#34;&gt;LAL定义&lt;/h3&gt;
&lt;p&gt;在 filter 中，我们通过条件判断，只处理 &lt;code&gt;service=nginx::nginx&lt;/code&gt; 的服务，其他服务依旧走默认逻辑：&lt;/p&gt;
&lt;p&gt;第一步，使用 json 指令对日志进行解析，解析的结果会被存放到 parsed 字段中，通过 parsed 字段我们可以获取 json 日志中的字段信息。&lt;/p&gt;
&lt;p&gt;第二步，使用 timestamp 指令解析 parsed.time 并将其赋值给日志的 timestamp 字段，这里的 time 就是access log json 中的 time。&lt;/p&gt;
&lt;p&gt;第三步，使用 tag 指令给日志打上对应的标签，标签的值依然可以通过 parsed 字段获取。&lt;/p&gt;
&lt;p&gt;第四步，使用 metrics 指令从日志中提取出指标信息，我们共提取了四个指标：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nginx_log_count&lt;/code&gt;：Nginx 每次请求都会生成一条 access log，该指标可以帮助我们统计 Nginx 当前的请求数。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nginx_request_time&lt;/code&gt;：access log 中会记录请求时间，该指标可以帮助我们统计上游接口的响应时长。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nginx_body_bytes_sent&lt;/code&gt;：body 大小指标可以帮助我们了解网关上的流量情况。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nginx_status_code&lt;/code&gt;：状态码指标可以实现对状态码的监控，如果出现异常上涨可以结合 alarm 进行告警。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;rules&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#0550ae&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;default&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;layer&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;GENERAL&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;dsl&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;|&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;      filter {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;        if (log.service == &amp;#34;nginx::nginx&amp;#34;) {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;          json {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;            abortOnFailure true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;          }&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;          &lt;/span&gt;extractor {&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;            &lt;/span&gt;timestamp parsed.time as String, &amp;#34;yyyy-MM-dd&amp;#39;T&amp;#39;HH:mm:ssXXX&amp;#34;&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;tag status&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;parsed.status&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;tag remote_addr&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;parsed.remote_addr&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;      
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;            &lt;/span&gt;metrics {&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;timestamp log.timestamp as Long&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;labels service: log.service, instance&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;log.serviceInstance&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;name &amp;#34;nginx_log_count&amp;#34;&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;value 1&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;            &lt;/span&gt;}&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;            &lt;/span&gt;metrics {&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;timestamp log.timestamp as Long&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;labels service: log.service, instance&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;log.serviceInstance&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;name &amp;#34;nginx_request_time&amp;#34;&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;value parsed.request_time as Double&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;            &lt;/span&gt;}&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;            &lt;/span&gt;metrics {&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;timestamp log.timestamp as Long&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;labels service: log.service, instance&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;log.serviceInstance&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;name &amp;#34;nginx_body_bytes_sent&amp;#34;&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;value parsed.body_bytes_sent as Long&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;            &lt;/span&gt;}&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;            &lt;/span&gt;metrics {&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;timestamp log.timestamp as Long&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;labels service: log.service, instance: log.serviceInstance, status&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;parsed.status&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;name &amp;#34;nginx_status_code&amp;#34;&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;              &lt;/span&gt;value 1&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;            &lt;/span&gt;}&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;          &lt;/span&gt;}&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;      
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;        &lt;/span&gt;sink {&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;      &lt;/span&gt;}&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;经过 LAL 处理后，我们已经可以在日志面板看到日志信息了，接下来我们将对 LAL 中提取的指标进行进一步分析：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;./nginx-log.jpg&#34; alt=&#34;nginx-log&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;mal定义&#34;&gt;MAL定义&lt;/h3&gt;
&lt;p&gt;在 MAL 中，我们可以对上一步 LAL 中提取的指标进行进一步的分析聚合，下面的例子里：&lt;/p&gt;
&lt;p&gt;nginx_log_count、nginx_request_time、nginx_status_code 使用 sum 聚合函数处理，并使用 SUM 方式 downsampling，&lt;/p&gt;
&lt;p&gt;nginx_request_time 使用 avg 聚合函数求平均值，默认使用 AVG 方式 downsampling。&lt;/p&gt;
&lt;p&gt;完成聚合分析后，SkyWalking Meter System 会完成对上述指标的持久化。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;expSuffix&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;service([&amp;#39;service&amp;#39;], Layer.GENERAL)&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;metricPrefix&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;nginx&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;metricsRules&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#0550ae&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;cpm&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;exp&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;nginx_log_count.sum([&amp;#39;service&amp;#39;]).downsampling(SUM)&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#0550ae&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;avg_request_time&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;exp&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;nginx_request_time.avg([&amp;#39;service&amp;#39;])&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#0550ae&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;body_bytes_sent_count&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;exp&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;nginx_body_bytes_sent.sum([&amp;#39;service&amp;#39;]).downsampling(SUM)&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#0550ae&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;status_code_count&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;exp&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;nginx_status_code.sum([&amp;#39;service&amp;#39;,&amp;#39;status&amp;#39;]).downsampling(SUM)&lt;span style=&#34;color:#fff&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最后，我们便可以来到 SkyWalking UI 页面新建 Nginx 仪表板，使用刚刚 MAL 中定义的指标信息创建 Nginx Dashboard（也可以通过上文提到&lt;a href=&#34;https://github.com/weixiang1862/nginx-fluent-bit&#34;&gt;仓库&lt;/a&gt;中的 dashboard.json 直接导入测试）：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;./nginx-metric.jpg&#34; alt=&#34;nginx-metric&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;参考文档&#34;&gt;参考文档&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.fluentbit.io/manual/pipeline/filters/lua&#34;&gt;Fluent Bit lua Filter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skywalking.apache.org/docs/main/next/en/concepts-and-designs/lal/&#34;&gt;Log Analysis Language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skywalking.apache.org/docs/main/next/en/concepts-and-designs/mal/&#34;&gt;Meter Analysis Language&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Blog: How to integrate skywalking-nginx-lua to Nginx?</title>
      <link>/blog/2021-12-13-skywalking-nginx-agent-integration/</link>
      <pubDate>Mon, 13 Dec 2021 00:00:00 +0000</pubDate>
      <guid>/blog/2021-12-13-skywalking-nginx-agent-integration/</guid>
      <description>
        
        
        &lt;p&gt;We Can integrate Skywalking to Java Application by Java Agent TEC.， In typical application, the system runs Java Web applications at the backend of the load balancer, and the most commonly used load balancer is nginx. What should we do if we want to bring it under surveillance? Fortunately, skywalking has provided &lt;a href=&#34;https://github.com/apache/skywalking-nginx-lua&#34;&gt;Nginx agent&lt;/a&gt;。 During the integration process, it is found that the examples on the official website only support openresty. For openresty, common modules such as luajit and Lua nginx module have been integrated. Adding skywalking related configurations according to the examples on the official website can take effect. However, when configured for nginx startup, many errors will be reported. We may not want to change a load balancer (nginx to openresty) in order to use skywalking. Therefore, we must solve the integration problem between skywalking and nginx.&lt;/p&gt;
&lt;p&gt;Note: openresty is a high-performance web development platform based on nginx + Lua, which solves the short board that is not easy to program in nginx.&lt;/p&gt;
&lt;p&gt;Based on Skywalking-8.7.0 and Nginx-1.20.1&lt;/p&gt;
&lt;h3 id=&#34;upgrade-of-nginx&#34;&gt;Upgrade of nginx:&lt;/h3&gt;
&lt;p&gt;The agent plug-in of nginx is written based on Lua, so nginx needs to add support for Lua, &lt;a href=&#34;https://github.com/openresty/lua-nginx-module&#34;&gt;Lua nginx module&lt;/a&gt; It just provides this function. The Lua nginx module depends on &lt;a href=&#34;https://luajit.org/download.html&#34;&gt;luajit&lt;/a&gt; Therefore, first we need to install luajit. In the environment, it is best to choose version 2.1.&lt;/p&gt;
&lt;p&gt;For nginx, you need to compile the necessary modules yourself. It depends on the following two modules:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/openresty/lua-nginx-module&#34;&gt;lua-nginx-module&lt;/a&gt; The version is lua-nginx-module-0.10.21rc1&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://openresty.org/cn/nginx-devel-kit.html&#34;&gt;ngx_devel_kit&lt;/a&gt; The version using ngx_devel_kit-0.3.1&lt;/p&gt;
&lt;p&gt;Compile nginx parameters&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;configure arguments: --add-module&lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt;/path/to/ngx_devel_kit-0.3.1 --add-module&lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt;/path/to/lua-nginx-module-0.10.21rc1 --with-ld-opt&lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt;-Wl,-rpath,/usr/local/LuaJIT/lib
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The following is for skywalking-nginx-lua-0.3.0 and 0.3.0+ are described separately.&lt;/p&gt;
&lt;h3 id=&#34;skywalking-nginx-lua-030&#34;&gt;skywalking-nginx-lua-0.3.0&lt;/h3&gt;
&lt;p&gt;After testing, skywalking-nginx-lua-0.3.0 requires the following Lua related modules&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lua-resty-core https://github.com/openresty/lua-resty-core
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lua-resty-lrucache https://github.com/openresty/lua-resty-lrucache
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lua-cjson https://github.com/openresty/lua-cjson
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The dependent Lua modules are as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lua_package_path &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;/path/to/lua-resty-core/lua-resty-core-master/lib/?.lua;/path/to/lua-resty-lrucache-0.11/lib/?.lua;/path/to/skywalking-nginx-lua-0.3.0/lib/?.lua;;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the process of make &amp;amp; &amp;amp; make install, Lua cjson needs to pay attention to:&lt;/p&gt;
&lt;p&gt;Modify a path in makefile&lt;/p&gt;
&lt;p&gt;LUA_INCLUDE_DIR ?= /usr/local/LuaJIT/include/luajit-2.0&lt;/p&gt;
&lt;p&gt;Reference:&lt;a href=&#34;https://blog.csdn.net/ymeputer/article/details/50146143&#34;&gt; https://blog.csdn.net/ymeputer/article/details/50146143 &lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;skywalking-nginx-lua-030-1&#34;&gt;skywalking-nginx-lua-0.3.0+&lt;/h3&gt;
&lt;p&gt;For skywalking-nginx-lua-0.3.0+, tablepool support needs to be added, but it seems that cjson is not required&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lua-resty-core https://github.com/openresty/lua-resty-core
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lua-resty-lrucache https://github.com/openresty/lua-resty-lrucache
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lua-tablepool https://github.com/openresty/lua-tablepool
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lua_ package_ path &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;/path/to/lua-resty-core/lua-resty-core-master/lib/?.lua;/path/to/lua-resty-lrucache-0.11/lib/?.lua;/path/to/lua-tablepool-master/lib/?.lua;/path/to/skywalking-nginx-lua-master/lib/?.lua;;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;tablepool introduces two APIs according to its official documents &lt;code&gt;table new and table. Clear&lt;/code&gt; requires luajit2.1, there is a paragraph in the skywalking-nginx-lua document that says you can use &amp;lsquo;require (&amp;ldquo;skywalking. Util&amp;rdquo;) disable_ Tablepool() ` disable tablepool&lt;/p&gt;
&lt;p&gt;When you start nginx, you will be prompted to install openresty&amp;rsquo;s own [luajit version]（ &lt;a href=&#34;https://github.com/openresty/luajit2&#34;&gt;https://github.com/openresty/luajit2&lt;/a&gt; )&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;detected a LuaJIT version which is not OpenResty&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#39;s; many optimizations will be disabled and performance will be compromised (see https://github.com/openresty/luajit2 for OpenResty&amp;#39;&lt;/span&gt;s LuaJIT or, even better, consider using the OpenResty releases from https://openresty.org/en/download.html &lt;span style=&#34;color:#0550ae&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;here is successful configuration:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     http &lt;span style=&#34;color:#1f2328&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    lua_package_path &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;/path/to/lua-resty-core/lua-resty-core-master/lib/?.lua;/path/to/lua-resty-lrucache-0.11/lib/?.lua;/path/to/lua-tablepool-master/lib/?.lua;/path/to/skywalking-nginx-lua-master/lib/?.lua;;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#0550ae&#34;&gt;#&lt;/span&gt; Buffer represents the register inform &lt;span style=&#34;color:#0550ae&#34;&gt;and&lt;/span&gt; the queue of the finished segment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    lua_shared_dict tracing_buffer &lt;span style=&#34;color:#0550ae&#34;&gt;100&lt;/span&gt;m&lt;span style=&#34;color:#1f2328&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#0550ae&#34;&gt;#&lt;/span&gt; Init is the timer setter &lt;span style=&#34;color:#0550ae&#34;&gt;and&lt;/span&gt; keeper
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#0550ae&#34;&gt;#&lt;/span&gt; Setup an infinite loop timer to &lt;span style=&#34;color:#cf222e&#34;&gt;do&lt;/span&gt; register &lt;span style=&#34;color:#0550ae&#34;&gt;and&lt;/span&gt; trace report&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    init_worker_by_lua_block &lt;span style=&#34;color:#1f2328&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#cf222e&#34;&gt;local&lt;/span&gt; metadata_buffer &lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt; ngx.shared&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;tracing_buffer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#57606a&#34;&gt;-- Set service name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        metadata_buffer&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;set&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#39;serviceName&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#39;User Service Name&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#57606a&#34;&gt;-- Instance means the number of Nginx deployment, does not mean the worker instances&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        metadata_buffer&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;set&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#39;serviceInstanceName&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#39;User Service Instance Name&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#57606a&#34;&gt;-- type &amp;#39;boolean&amp;#39;, mark the entrySpan include host/domain&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        metadata_buffer&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;set&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#39;includeHostInEntrySpan&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#57606a&#34;&gt;-- set random seed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        require&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;skywalking.util&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;).&lt;/span&gt;set_randomseed&lt;span style=&#34;color:#1f2328&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        require&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;skywalking.client&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;):&lt;/span&gt;startBackendTimer&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;http://127.0.0.1:12800&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#57606a&#34;&gt;-- If there is a bug of this `tablepool` implementation, we can&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#57606a&#34;&gt;-- disable it in this way&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#57606a&#34;&gt;-- require(&amp;#34;skywalking.util&amp;#34;).disable_tablepool()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        skywalking_tracer &lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt; require&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;skywalking.tracer&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#1f2328&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    server &lt;span style=&#34;color:#1f2328&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        listen &lt;span style=&#34;color:#0550ae&#34;&gt;8090&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        location &lt;span style=&#34;color:#0550ae&#34;&gt;/&lt;/span&gt;ingress &lt;span style=&#34;color:#1f2328&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            default_type text&lt;span style=&#34;color:#0550ae&#34;&gt;/&lt;/span&gt;html&lt;span style=&#34;color:#1f2328&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            rewrite_by_lua_block &lt;span style=&#34;color:#1f2328&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#57606a&#34;&gt;------------------------------------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#57606a&#34;&gt;-- NOTICE, this should be changed manually&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#57606a&#34;&gt;-- This variable represents the upstream logic address&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#57606a&#34;&gt;-- Please set them as service logic name or DNS name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#57606a&#34;&gt;--&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#57606a&#34;&gt;-- Currently, we can not have the upstream real network address&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#57606a&#34;&gt;------------------------------------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                skywalking_tracer&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;start&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;upstream service&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#57606a&#34;&gt;-- If you want correlation custom data to the downstream service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#57606a&#34;&gt;-- skywalking_tracer:start(&amp;#34;upstream service&amp;#34;, {custom = &amp;#34;custom_value&amp;#34;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#1f2328&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#57606a&#34;&gt;-- Target upstream service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            proxy_pass http&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;//&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;127.0.0.1&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;8080&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;/&lt;/span&gt;backend&lt;span style=&#34;color:#1f2328&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            body_filter_by_lua_block &lt;span style=&#34;color:#1f2328&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#cf222e&#34;&gt;if&lt;/span&gt; ngx.arg&lt;span style=&#34;color:#1f2328&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    skywalking_tracer&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;finish&lt;span style=&#34;color:#1f2328&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#cf222e&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#1f2328&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            log_by_lua_block &lt;span style=&#34;color:#1f2328&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                skywalking_tracer&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt;prepareForReport&lt;span style=&#34;color:#1f2328&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#1f2328&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#1f2328&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#1f2328&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Original post：https://www.cnblogs.com/kebibuluan/p/14440228.html&lt;/p&gt;

      </description>
    </item>
    
  </channel>
</rss>
