<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Apache SkyWalking – Logging</title>
    <link>/tags/logging/</link>
    <description>Recent content in Logging on Apache SkyWalking</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Tue, 23 Jun 2026 00:00:00 +0000</lastBuildDate>
    
	  <atom:link href="/tags/logging/feed.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Blog: Meet Horizon UI · 7/17: The Log Explorer</title>
      <link>/blog/2026-06-23-horizon-ui-log-explorer/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/blog/2026-06-23-horizon-ui-log-explorer/</guid>
      <description>
        
        
        &lt;p&gt;This is the seventh post in the &lt;a href=&#34;/blog/2026-06-21-skywalking-horizon-ui-introduction/&#34;&gt;Meet Horizon UI&lt;/a&gt; series. &lt;a href=&#34;/blog/2026-06-22-horizon-ui-trace-explorer/&#34;&gt;Part 6&lt;/a&gt; was one request&amp;rsquo;s spans; this one is the log lines around it. Horizon surfaces logs through &lt;strong&gt;two distinct tabs&lt;/strong&gt;, because there are really two different questions: &lt;em&gt;&amp;ldquo;what did this service log over the last half hour?&amp;rdquo;&lt;/em&gt; and &lt;em&gt;&amp;ldquo;what is this pod printing to stdout right now?&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Logs&lt;/strong&gt; tab queries the logs SkyWalking has already &lt;strong&gt;collected and stored&lt;/strong&gt; — indexed, filterable, correlated with traces.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Pod Logs&lt;/strong&gt; tab &lt;strong&gt;live-tails&lt;/strong&gt; a Kubernetes pod&amp;rsquo;s container logs &lt;em&gt;on demand&lt;/em&gt; — these aren&amp;rsquo;t stored logs at all: OAP reads them straight from the &lt;strong&gt;Kubernetes API server&lt;/strong&gt; (the &lt;code&gt;kubectl logs&lt;/code&gt; path), Horizon shows the window, and it&amp;rsquo;s discarded. Nothing is persisted, and SkyWalking&amp;rsquo;s log storage is never involved.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Which tabs a layer shows is up to its template: the &lt;strong&gt;Logs&lt;/strong&gt; tab appears on layers that enable it (General, Mesh, Nginx, the Envoy AI Gateway, the mobile and mini-program layers); the &lt;strong&gt;Pod Logs&lt;/strong&gt; tab appears only on the Kubernetes-aware layers (Kubernetes Service, Mesh, Mesh data plane). Browser JavaScript errors are a different thing again — not service logs but client-side error events the browser agent reports, with their own categories and their own &lt;strong&gt;source-map de-obfuscation&lt;/strong&gt; (turning a minified &lt;code&gt;app.min.js:1:…&lt;/code&gt; frame back into your original &lt;code&gt;file:line&lt;/code&gt;). That&amp;rsquo;s a separate tab on the Browser layer, and its own post later in the series.&lt;/p&gt;
&lt;h2 id=&#34;the-stored-log-stream&#34;&gt;The stored log stream&lt;/h2&gt;
&lt;p&gt;Open a layer that has a &lt;strong&gt;Logs&lt;/strong&gt; tab, pick a service in the header, and its stored log stream loads newest-first. Like the trace explorer, this tab &lt;strong&gt;owns its own time range&lt;/strong&gt; — the global topbar picker is paused while you&amp;rsquo;re here, so auto-refresh can&amp;rsquo;t shift the window out from under an investigation. Pick a rolling preset (last 15 minutes through 24 hours, default 30) or a custom absolute window; queries run at &lt;strong&gt;second precision&lt;/strong&gt; so the most recent lines are never rounded off the minute.&lt;/p&gt;
&lt;p&gt;A conditions bar narrows the stream, and every filter is optional and AND-joined:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Instance&lt;/strong&gt; — restrict to one service instance (labelled &lt;strong&gt;Sidecar&lt;/strong&gt; on a sidecar layer).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Endpoint&lt;/strong&gt; — type to search the service&amp;rsquo;s endpoints, click to pin, &lt;strong&gt;×&lt;/strong&gt; to clear.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trace ID&lt;/strong&gt; — show only the lines correlated with one trace. This is also how a log lands when you arrive &lt;em&gt;from&lt;/em&gt; a trace: the field pre-fills and the stream is already scoped.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tags&lt;/strong&gt; — a single &lt;code&gt;key=value&lt;/code&gt; field with autocomplete; start a key to see suggestions, type &lt;code&gt;=&lt;/code&gt; to switch to known values, Enter to commit. Committed tags ride along as removable chips.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Level&lt;/strong&gt; — the &lt;strong&gt;Levels&lt;/strong&gt; strip above the stream doubles as a filter: click &lt;code&gt;error&lt;/code&gt;, &lt;code&gt;warn&lt;/code&gt;, &lt;code&gt;info&lt;/code&gt;, or &lt;code&gt;debug&lt;/code&gt; to keep only that level, click again to clear.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There&amp;rsquo;s no log query language here — no LogQL box to learn. The conditions above are the whole surface, and &lt;strong&gt;edits refresh the stream as you make them&lt;/strong&gt;; &lt;strong&gt;Run query&lt;/strong&gt; is just the explicit &amp;ldquo;I&amp;rsquo;m done editing, refresh now&amp;rdquo; button that resets to the first page.&lt;/p&gt;
&lt;h2 id=&#34;reading-the-stream&#34;&gt;Reading the stream&lt;/h2&gt;
&lt;p&gt;The point of a log view isn&amp;rsquo;t to &lt;em&gt;list&lt;/em&gt; lines, it&amp;rsquo;s to find the shape in them — so the stream comes with two pieces of orientation above it.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;density histogram&lt;/strong&gt; plots log count over time, each bar &lt;strong&gt;stacked by level&lt;/strong&gt; in the legend&amp;rsquo;s colors; hover a bar for that bucket&amp;rsquo;s time range and per-level counts. It&amp;rsquo;s drawn from the page currently on screen, so it shows the shape of what you&amp;rsquo;re looking at. And the &lt;strong&gt;Levels&lt;/strong&gt; strip carries a running count per level — sampled across the window, not just the visible page, so the error/warn/info mix reflects the whole window you&amp;rsquo;re querying.&lt;/p&gt;
&lt;p&gt;Each row then shows the timestamp, the level (the row is color-keyed to it), the service, an &lt;strong&gt;↗ trace&lt;/strong&gt; link when the line is trace-correlated, a &lt;strong&gt;&lt;code&gt;JSON&lt;/code&gt; / &lt;code&gt;YAML&lt;/code&gt; / &lt;code&gt;TEXT&lt;/code&gt; format chip&lt;/strong&gt;, and a one-line preview of the content. Horizon decides that chip by what the payload actually &lt;em&gt;is&lt;/em&gt;: OAP labels a body JSON or plain text, and on top of that Horizon sniffs for JSON and YAML structure, so an unlabelled-but-structured line still gets the right treatment — JSON flattened to one line in the preview, YAML keeping its keys, plain text whitespace-collapsed.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/screenshots/horizon-0.7.0/p07-logs-01-stream.webp&#34; alt=&#34;Figure 1: The stored Logs stream — the conditions bar, the level-stacked density histogram and Levels strip above, and the log rows below, each with its level color, service, format chip, and an ↗ trace link.&#34;&gt;
Figure 1: A service&amp;rsquo;s stored log stream — a level histogram and level counts over the window, then the rows, each tagged JSON / YAML / TEXT and linked to its trace.&lt;/br&gt;&lt;/p&gt;
&lt;h2 id=&#34;into-a-single-line&#34;&gt;Into a single line&lt;/h2&gt;
&lt;p&gt;Click a row and the full payload opens in a popout: the complete content with &lt;strong&gt;format-aware pretty-printing&lt;/strong&gt; — JSON and YAML laid out properly, plain text given the whole canvas instead of a cramped strip — plus a &lt;strong&gt;Copy&lt;/strong&gt; button, the service / instance / endpoint / trace context, and a table of every tag on the line. When the line is trace-correlated, an &lt;strong&gt;↗ trace&lt;/strong&gt; button opens the related &lt;a href=&#34;/blog/2026-06-22-horizon-ui-trace-explorer/&#34;&gt;trace&amp;rsquo;s waterfall&lt;/a&gt; in an overlay without leaving the stream — and it passes the row&amp;rsquo;s timestamp along, so the trace is found even when it has aged into a colder storage tier. Escape or a backdrop click closes it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/screenshots/horizon-0.7.0/p07-logs-02-payload.webp&#34; alt=&#34;Figure 2: A log line&amp;rsquo;s payload popout — the full content pretty-printed by format (a JSON access log here), a Copy button, the service and instance context, and the line&amp;rsquo;s tag table (here status.code).&#34;&gt;
Figure 2: One line in full — its payload pretty-printed by format, with its context and every tag laid out beside it.&lt;/br&gt;&lt;/p&gt;
&lt;h2 id=&#34;pod-logs-tailing-whats-printing-right-now&#34;&gt;Pod Logs: tailing what&amp;rsquo;s printing right now&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;Pod Logs&lt;/strong&gt; tab answers the other question, and it&amp;rsquo;s a fundamentally different source: not SkyWalking&amp;rsquo;s stored logs, but the pod&amp;rsquo;s container output read live from the &lt;strong&gt;Kubernetes API server&lt;/strong&gt; through OAP — the exact thing &lt;code&gt;kubectl logs -f&lt;/code&gt; reads. There&amp;rsquo;s no stored history to page through; each refresh pulls the trailing window, shows it, and throws it away.&lt;/p&gt;
&lt;p&gt;Starting a tail is a few picks: choose a &lt;strong&gt;Pod&lt;/strong&gt; (one service instance, pinned), a &lt;strong&gt;Container&lt;/strong&gt; (Horizon lists the pod&amp;rsquo;s containers and selects the first), a look-back &lt;strong&gt;Window&lt;/strong&gt; (last 30s, 1m, 5m, 15m, or 30m — how far back each poll reaches), and a poll &lt;strong&gt;Interval&lt;/strong&gt; (2s, 5s, 10s, or 30s — how often it re-fetches). Press &lt;strong&gt;Start&lt;/strong&gt; and the window streams into a read-only viewer that keeps the newest line in view and re-polls until you &lt;strong&gt;Pause&lt;/strong&gt;; a header strip shows the container, the line count, a live indicator, and how long ago it last updated. Two &lt;strong&gt;Include&lt;/strong&gt; / &lt;strong&gt;Exclude&lt;/strong&gt; filter rows narrow what you see — each chip is a &lt;strong&gt;full-line regular expression&lt;/strong&gt; (&lt;code&gt;.*error.*&lt;/code&gt;) evaluated by OAP, so they match the whole line rather than a substring, and they stack.&lt;/p&gt;
&lt;p&gt;One thing to know going in: on-demand pod logs are &lt;strong&gt;disabled by default on OAP&lt;/strong&gt;, because container output can carry secrets. When the feature is off — or when the pod you picked has been rolled or scaled away — OAP returns a &lt;em&gt;reason&lt;/em&gt;, and Horizon shows it in a banner rather than an empty pane, so you can tell &amp;ldquo;turn this on&amp;rdquo; apart from &amp;ldquo;that pod is gone.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/screenshots/horizon-0.7.0/p07-logs-03-pod-logs.webp&#34; alt=&#34;Figure 3: The Pod Logs tab — the pod and container pickers, the look-back window and poll interval, the live-indicator header strip, the Include/Exclude regex chips, and the read-only tail pane streaming the container&amp;rsquo;s recent output.&#34;&gt;
Figure 3: A live tail of one pod&amp;rsquo;s container — windowed, interval-polled, regex-filterable, never persisted.&lt;/br&gt;&lt;/p&gt;
&lt;h2 id=&#34;where-to-go-next&#34;&gt;Where to go next&lt;/h2&gt;
&lt;p&gt;Both tabs — the stored queries, the tag and container autocomplete, and the live tail — are gated by a single &lt;code&gt;logs:read&lt;/code&gt; permission, so granting &amp;ldquo;can read logs&amp;rdquo; is one switch. For the field reference — every condition, the histogram, the Pod Logs windows and filters — see the &lt;a href=&#34;https://skywalking.apache.org/docs/skywalking-horizon-ui/next/operate/logs/&#34;&gt;Logs docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next up: &lt;a href=&#34;/blog/2026-06-23-horizon-ui-browser-errors-and-source-maps/&#34;&gt;&lt;strong&gt;Browser &amp;amp; RUM monitoring&lt;/strong&gt;&lt;/a&gt; — the browser agent&amp;rsquo;s own error stream, and de-obfuscating a minified stack with source maps.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Blog: Meet Horizon UI · 8/17: Browser Errors &amp; Source Maps</title>
      <link>/blog/2026-06-23-horizon-ui-browser-errors-and-source-maps/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/blog/2026-06-23-horizon-ui-browser-errors-and-source-maps/</guid>
      <description>
        
        
        &lt;p&gt;This is the eighth post in the &lt;a href=&#34;/blog/2026-06-21-skywalking-horizon-ui-introduction/&#34;&gt;Meet Horizon UI&lt;/a&gt; series. &lt;a href=&#34;/blog/2026-06-23-horizon-ui-log-explorer/&#34;&gt;Part 7&lt;/a&gt; was your services&amp;rsquo; logs; this one is your &lt;em&gt;users&amp;rsquo;&lt;/em&gt; errors — the JavaScript exceptions the browser agent reports — and the one capability that turns them from noise into something you can act on.&lt;/p&gt;
&lt;p&gt;A production JavaScript stack is unreadable. Your code shipped minified and bundled, so the browser reports an error at &lt;code&gt;app.min.js:1:98412&lt;/code&gt; — a position into machine-generated soup that tells you nothing. The point of this feature is to walk that stack back to &lt;em&gt;your&lt;/em&gt; source: the original file, line, column, symbol name, and a snippet of the code around it — frame by frame — by pointing the error at the right &lt;strong&gt;source map&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&#34;the-browser-error-feed&#34;&gt;The browser-error feed&lt;/h2&gt;
&lt;p&gt;On the &lt;strong&gt;BROWSER&lt;/strong&gt; layer, the &lt;strong&gt;Browser Logs&lt;/strong&gt; tab (the on-screen label — it&amp;rsquo;s specifically the JavaScript-error feed) lists what your browser agent reports. The BROWSER layer renames its slots to match its world — services become &lt;strong&gt;Applications&lt;/strong&gt;, instances &lt;strong&gt;Versions&lt;/strong&gt;, endpoints &lt;strong&gt;Pages&lt;/strong&gt; — and the feed reads like the &lt;a href=&#34;/blog/2026-06-23-horizon-ui-log-explorer/&#34;&gt;Log Explorer&lt;/a&gt;: a clickable &lt;strong&gt;category&lt;/strong&gt; legend with counts and a density histogram over a stream of rows. Each row carries the time, the &lt;strong&gt;category&lt;/strong&gt;, the page, the app version, and the error message — with the minified &lt;code&gt;line:col&lt;/code&gt; shown as a chip when there is one.&lt;/p&gt;
&lt;p&gt;You scope it with the same triage instincts as the trace and log tabs: it owns its own &lt;strong&gt;Time range&lt;/strong&gt; (the global topbar is paused), and you narrow by &lt;strong&gt;Version&lt;/strong&gt;, &lt;strong&gt;Page&lt;/strong&gt;, or &lt;strong&gt;Category&lt;/strong&gt; and hit &lt;strong&gt;Run query&lt;/strong&gt; — there&amp;rsquo;s no background polling to shift the view under you, and no query language to learn, just structured controls. Click a row and it expands inline, right there in the stream.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/screenshots/horizon-0.7.0/p08-browser-01-stream.webp&#34; alt=&#34;Figure 1: The Browser Logs tab on the BROWSER layer — the category legend and density histogram over a stream of reported JS errors, each row showing its category, page, app version, and the minified line:col.&#34;&gt;
Figure 1: The browser agent&amp;rsquo;s error feed — categorized, charted, and scoped to one app&amp;rsquo;s version and pages.&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;That minified &lt;code&gt;line:col&lt;/code&gt; is the whole problem in miniature. It&amp;rsquo;s a real position — but into your &lt;em&gt;built&lt;/em&gt; bundle, not your source. Which is where the rest of this post comes in.&lt;/p&gt;
&lt;h2 id=&#34;from-a-minified-stack-back-to-your-source&#34;&gt;From a minified stack back to your source&lt;/h2&gt;
&lt;p&gt;Expand an error and the panel splits in two: on the left, the &lt;strong&gt;raw stack&lt;/strong&gt; exactly as the browser reported it (the gibberish); on the right, where you resolve it. Pick a &lt;strong&gt;source map&lt;/strong&gt; from the dropdown and click &lt;strong&gt;Resolve&lt;/strong&gt;, and Horizon parses the stack and maps &lt;strong&gt;every frame&lt;/strong&gt; through that map:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;each frame&amp;rsquo;s original &lt;strong&gt;&lt;code&gt;file:line:column&lt;/code&gt;&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;the original &lt;strong&gt;symbol name&lt;/strong&gt; (when the map carries it), and&lt;/li&gt;
&lt;li&gt;a few lines of the &lt;strong&gt;original source&lt;/strong&gt; around the offending line, with the hit line highlighted (when the map embeds &lt;code&gt;sourcesContent&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A frame the map doesn&amp;rsquo;t cover is shown honestly as &lt;code&gt;unmapped&lt;/code&gt;. So a stack whose top frame read &lt;code&gt;app.min.js:1:45&lt;/code&gt; resolves to &lt;code&gt;computeCartTotal&lt;/code&gt; at &lt;code&gt;checkout.ts:2:20&lt;/code&gt;, with the lines of &lt;code&gt;checkout.ts&lt;/code&gt; around it — the &lt;code&gt;cart.items.reduce(...)&lt;/code&gt; that actually threw — sitting right there, the whole stack top to bottom, not just the first frame.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s careful about the details that make this either trustworthy or quietly wrong: browser stacks count columns from 1 while source maps count from 0, so the resolver shifts before each lookup — and that path is tested against real bundler output, not a hand-made fixture.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/screenshots/horizon-0.7.0/p08-browser-02-resolve.webp&#34; alt=&#34;Figure 2: An expanded error — the raw minified stack on the left, and on the right the resolved stack, each frame showing the original file:line:column, the symbol, and a highlighted source snippet.&#34;&gt;
Figure 2: The hero — point a minified stack at the right map and read it back in your own source, frame by frame.&lt;/br&gt;&lt;/p&gt;
&lt;h2 id=&#34;which-errors-carry-a-stack-to-resolve&#34;&gt;Which errors carry a stack to resolve&lt;/h2&gt;
&lt;p&gt;Not every category has something to translate. &lt;strong&gt;&lt;code&gt;JS&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;PROMISE&lt;/code&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;code&gt;VUE&lt;/code&gt;&lt;/strong&gt; are real JavaScript errors whose stack points into your bundle — these resolve. &lt;strong&gt;&lt;code&gt;AJAX&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;RESOURCE&lt;/code&gt;&lt;/strong&gt; are network and load failures; their &amp;ldquo;stack&amp;rdquo; is an HTTP status or a failed URL, not code, so there&amp;rsquo;s simply nothing for a source map to map (Horizon doesn&amp;rsquo;t block them — there&amp;rsquo;s just no JavaScript there to walk back). Frames from code with no source map, or from &lt;code&gt;eval&lt;/code&gt;/inline scripts, stay &lt;code&gt;unmapped&lt;/code&gt; too. (&lt;code&gt;JS&lt;/code&gt; is also the only category the browser reports a top-level &lt;code&gt;line:col&lt;/code&gt; for; the others carry their position inside the stack string, which the resolver parses.)&lt;/p&gt;
&lt;h2 id=&#34;getting-maps-in-upload-or-mount&#34;&gt;Getting maps in: upload, or mount&lt;/h2&gt;
&lt;p&gt;A map has to be available before you can resolve against it, and there are two ways to provide one — deliberately different in durability:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Upload&lt;/strong&gt; a &lt;code&gt;.map&lt;/code&gt; straight from the tab. It&amp;rsquo;s held in the server&amp;rsquo;s &lt;strong&gt;memory only&lt;/strong&gt; — there&amp;rsquo;s no backend storage — and it&amp;rsquo;s temporary by design: it counts against a memory budget, is evicted least-recently-used under pressure, is &lt;strong&gt;lost when the server restarts&lt;/strong&gt;, and (in a multi-instance deployment) lives only on the instance that received it. This is the fast path for ad-hoc triage: drag a map in, resolve, move on.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mount&lt;/strong&gt; &lt;code&gt;.map&lt;/code&gt; files into the server&amp;rsquo;s &lt;strong&gt;source-map directory&lt;/strong&gt; (&lt;code&gt;/app/sourcemaps&lt;/code&gt; in the container image, via &lt;code&gt;HORIZON_SOURCEMAPS_DIR&lt;/code&gt;). These are validated as Source Map v3 at boot, read from disk on demand (so they never sit in the memory budget), survive restarts, reload on their own, and &lt;strong&gt;can&amp;rsquo;t be deleted from the UI&lt;/strong&gt;. This is the durable, production path — bake your builds&amp;rsquo; maps into the image and they&amp;rsquo;re always there.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The manager shows each map&amp;rsquo;s origin (an &lt;em&gt;uploaded · temporary&lt;/em&gt; map vs a &lt;em&gt;mounted · durable&lt;/em&gt; one) and the live memory usage against the budget; budgets (a per-file cap and a total resident-upload cap, 64 MiB and 512 MiB by default) live in a &lt;code&gt;sourceMaps&lt;/code&gt; block in &lt;code&gt;horizon.yaml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/screenshots/horizon-0.7.0/p08-browser-03-sourcemap-manager.webp&#34; alt=&#34;Figure 3: The source-map manager — the Upload .map control, the memory-budget bar (here 0 B / 512 MB, max 64 MB/file), and the loaded maps; the one shown is Mounted and durable, so it can&amp;rsquo;t be deleted here, while uploaded maps appear as temporary.&#34;&gt;
Figure 3: Two ways to provide a map — upload for a quick triage, mount for the durable, production set.&lt;/br&gt;&lt;/p&gt;
&lt;h2 id=&#34;you-pick-the-map--on-purpose&#34;&gt;You pick the map — on purpose&lt;/h2&gt;
&lt;p&gt;One thing Horizon deliberately does &lt;em&gt;not&lt;/em&gt; do is guess. The browser agent reports an app &lt;strong&gt;version&lt;/strong&gt; but no exact build fingerprint, so there&amp;rsquo;s no safe way to auto-match an error to a map — and applying a map from the &lt;em&gt;wrong&lt;/em&gt; build gives you confidently wrong line numbers, which is worse than no answer. So the choice is yours: pick the map that matches the error&amp;rsquo;s build, and keep your maps labelled by version. (One caution worth stating plainly: a source map&amp;rsquo;s &lt;code&gt;sourcesContent&lt;/code&gt; embeds your original source code, so treat the maps you upload or mount as sensitive, and provision them only on servers you trust.)&lt;/p&gt;
&lt;p&gt;That manual-by-design choice also draws a clean &lt;strong&gt;permission&lt;/strong&gt; line. Viewing the errors, listing the maps, and &lt;strong&gt;resolving&lt;/strong&gt; a stack are all reads, gated by &lt;code&gt;browser-errors:read&lt;/code&gt;; &lt;strong&gt;uploading or removing&lt;/strong&gt; a map is a write, gated by &lt;code&gt;source-map:write&lt;/code&gt;. So a read-only viewer can de-obfuscate stacks all day without ever being able to change what maps are loaded — reading is reading, mutating the map store is a write.&lt;/p&gt;
&lt;h2 id=&#34;where-to-go-next&#34;&gt;Where to go next&lt;/h2&gt;
&lt;p&gt;For the field reference — the categories, the two provisioning paths, the budgets and the matching-maps-to-builds guidance — see the &lt;a href=&#34;https://skywalking.apache.org/docs/skywalking-horizon-ui/next/operate/browser-source-maps/&#34;&gt;Browser Logs &amp;amp; Source Maps docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next up: &lt;a href=&#34;/blog/2026-06-26-horizon-ui-profiling/&#34;&gt;&lt;strong&gt;Profiling&lt;/strong&gt;&lt;/a&gt; — five profilers (trace, async, eBPF, Go pprof, network) rendered through one flame graph.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 认识 Horizon UI · 7/17：日志探索器</title>
      <link>/zh/2026-06-23-horizon-ui-log-explorer/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/zh/2026-06-23-horizon-ui-log-explorer/</guid>
      <description>
        
        
        &lt;p&gt;&lt;em&gt;译自英文原文：&lt;a href=&#34;/blog/2026-06-23-horizon-ui-log-explorer/&#34;&gt;Meet Horizon UI · 7/17: The Log Explorer&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;这是 &lt;a href=&#34;/zh/2026-06-21-skywalking-horizon-ui-introduction/&#34;&gt;Meet Horizon UI&lt;/a&gt; 系列的第七篇。&lt;a href=&#34;/zh/2026-06-22-horizon-ui-trace-explorer/&#34;&gt;第六篇&lt;/a&gt;讲的是一个请求的 spans；这一篇讲它周围的日志行。Horizon 用 &lt;strong&gt;两个标签页&lt;/strong&gt; 展示日志，对应两类排查问题：&lt;em&gt;“这个服务过去半小时打了什么日志？”&lt;/em&gt; 以及 &lt;em&gt;“这个 pod 现在正在向 stdout 打什么？”&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Logs&lt;/strong&gt; 标签页查询 SkyWalking 已经 &lt;strong&gt;采集并存储&lt;/strong&gt; 的日志：已索引、可过滤、可与 Trace 关联。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pod Logs&lt;/strong&gt; 标签页按需 &lt;strong&gt;实时 tail&lt;/strong&gt; Kubernetes pod 的容器日志。这类日志不走 SkyWalking 的日志存储：OAP 直接从 &lt;strong&gt;Kubernetes API server&lt;/strong&gt; 读取它们（也就是 &lt;code&gt;kubectl logs&lt;/code&gt; 那条路径），Horizon 只展示当前窗口，然后丢弃，不会持久化。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;某个 Layer 展示哪些标签页由模板决定：启用日志的 Layer（General、Mesh、Nginx、Envoy AI Gateway、mobile 和 mini-program Layer）会显示 &lt;strong&gt;Logs&lt;/strong&gt; 标签页；只有感知 Kubernetes 的 Layer（Kubernetes Service、Mesh、Mesh data plane）会显示 &lt;strong&gt;Pod Logs&lt;/strong&gt; 标签页。Browser JavaScript 错误又是另一类数据：它不是服务日志，而是浏览器端 agent 上报的客户端错误事件，有自己的分类，也可以借助 &lt;strong&gt;source map&lt;/strong&gt; 把压缩后的 &lt;code&gt;app.min.js:1:...&lt;/code&gt; frame 还原到原始 &lt;code&gt;file:line&lt;/code&gt;。这是 Browser Layer 上的独立标签页，会在这个系列的另一篇文章里讲。&lt;/p&gt;
&lt;h2 id=&#34;查询已存储日志&#34;&gt;查询已存储日志&lt;/h2&gt;
&lt;p&gt;打开一个有 &lt;strong&gt;Logs&lt;/strong&gt; 标签页的 Layer，先在顶部选择服务，日志流会按新到旧加载。和 Trace 探索器一样，这个标签页使用 &lt;strong&gt;独立的时间范围&lt;/strong&gt;。当你在这里排查时，全局顶栏时间选择器会暂停，自动刷新不会把你正在看的窗口不断往前推。可以选择滚动预设（最近 15 分钟到 24 小时，默认 30 分钟），也可以选择自定义绝对窗口；查询按 &lt;strong&gt;秒级精度&lt;/strong&gt; 执行，所以最新日志不会被分钟取整吞掉。&lt;/p&gt;
&lt;p&gt;条件栏用来收窄日志流，每个过滤条件都是可选的，多个条件按 AND 连接：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Instance&lt;/strong&gt;：限制到某个服务实例。在 sidecar Layer 上标签显示为 &lt;strong&gt;Sidecar&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Endpoint&lt;/strong&gt;：输入搜索服务 endpoints，点击固定，按 &lt;strong&gt;×&lt;/strong&gt; 清除。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trace ID&lt;/strong&gt;：只显示和某条 Trace 关联的日志行。从 Trace 跳转过来时，也会预填这个字段并直接限定日志流。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tags&lt;/strong&gt;：单个 &lt;code&gt;key=value&lt;/code&gt; 字段，带 autocomplete；输入 key 可看建议，输入 &lt;code&gt;=&lt;/code&gt; 后切换到已知 value，按 Enter 提交。提交后的 tags 以可删除标签形式保留。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Level&lt;/strong&gt;：日志流上方的 &lt;strong&gt;Levels&lt;/strong&gt; 条也可以当过滤器用。点击 &lt;code&gt;error&lt;/code&gt;、&lt;code&gt;warn&lt;/code&gt;、&lt;code&gt;info&lt;/code&gt; 或 &lt;code&gt;debug&lt;/code&gt; 只保留该级别，再点一次清除。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里不提供单独的日志查询语言，也不需要学习 LogQL。上面的条件就是完整界面，并且 &lt;strong&gt;编辑时会立即刷新日志流&lt;/strong&gt;；&lt;strong&gt;Run query&lt;/strong&gt; 只是显式告诉系统“我改完了，现在刷新”，同时回到第一页。&lt;/p&gt;
&lt;h2 id=&#34;用直方图和级别计数定位日志&#34;&gt;用直方图和级别计数定位日志&lt;/h2&gt;
&lt;p&gt;日志视图的目标不只是 &lt;em&gt;列出&lt;/em&gt; 行，还要帮你看出分布和异常，所以日志流上方有两类辅助信息。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Density histogram&lt;/strong&gt; 按时间展示日志量，每个柱按 legend 颜色 &lt;strong&gt;堆叠 level&lt;/strong&gt;；hover 柱子可以看到该 bucket 的时间范围和每个 level 的计数。它基于当前页面上可见数据绘制，所以展示的是你正在看的日志分布。&lt;strong&gt;Levels&lt;/strong&gt; 条则保留每个 level 在窗口内的累计计数。这个计数跨整个查询窗口采样，而不只是当前可见页，所以 error/warn/info 比例反映的是整个窗口。&lt;/p&gt;
&lt;p&gt;日志行会展示 timestamp、level（行颜色跟随 level）、service、存在 Trace 关联时的 &lt;strong&gt;↗ trace&lt;/strong&gt; 链接、&lt;strong&gt;&lt;code&gt;JSON&lt;/code&gt; / &lt;code&gt;YAML&lt;/code&gt; / &lt;code&gt;TEXT&lt;/code&gt; 格式标记&lt;/strong&gt;，以及内容的一行预览。Horizon 按日志内容本身决定这个标记：OAP 会标注日志 body 是 JSON 还是 plain text，在此基础上 Horizon 还会识别 JSON 和 YAML 结构，所以即使一行没有被标注但内容是结构化的，也会得到正确处理。JSON 在预览里压平成一行，YAML 保留 key，plain text 会折叠空白。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/screenshots/horizon-0.7.0/p07-logs-01-stream.webp&#34; alt=&#34;图 1：存储 Logs 流。条件栏、按 level 堆叠的 density histogram 和 Levels 条在上方，下面是日志行，每行带 level 颜色、service、格式标记和 ↗ trace 链接。&#34;&gt;
图 1：某个服务的存储日志流：窗口上的 level histogram 和 level 计数，下面是每行日志，带 JSON / YAML / TEXT 标记并可跳到 Trace。&lt;/br&gt;&lt;/p&gt;
&lt;h2 id=&#34;查看单行日志详情&#34;&gt;查看单行日志详情&lt;/h2&gt;
&lt;p&gt;点击一行后，完整日志内容会在弹层里打开：内容会按格式排版，JSON 和 YAML 正常缩进，plain text 则展开成完整内容，而不是被挤在一条窄条里。面板还提供 &lt;strong&gt;Copy&lt;/strong&gt; 按钮、service / instance / endpoint / trace 上下文，以及该行所有 tag 的表格。日志行与 Trace 关联时，&lt;strong&gt;↗ trace&lt;/strong&gt; 按钮会在 overlay 中打开相关 &lt;a href=&#34;/zh/2026-06-22-horizon-ui-trace-explorer/&#34;&gt;Trace 瀑布图&lt;/a&gt;，不离开日志流；它还会把这行日志的 timestamp 传过去，所以 Trace 即使已经进入更冷的存储 tier，也仍然能找到。按 Escape 或点击背景遮罩即可关闭。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/screenshots/horizon-0.7.0/p07-logs-02-payload.webp&#34; alt=&#34;图 2：日志行详情弹层。完整内容按格式 pretty-print（这里是 JSON access log），带 Copy 按钮、service 和 instance 上下文，以及该行 tag 表（这里是 status.code）。&#34;&gt;
图 2：完整查看一行日志：内容按格式排版，旁边展示上下文和所有 tags。&lt;/br&gt;&lt;/p&gt;
&lt;h2 id=&#34;pod-logs实时查看容器输出&#34;&gt;Pod Logs：实时查看容器输出&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Pod Logs&lt;/strong&gt; 标签页回答另一个问题，它的数据源也完全不同：不是 SkyWalking 存储的日志，而是通过 OAP 从 &lt;strong&gt;Kubernetes API server&lt;/strong&gt; 实时读取 pod 的容器输出，也就是 &lt;code&gt;kubectl logs -f&lt;/code&gt; 读取的同一类内容。这里没有可翻页的存储历史；每次刷新拉取尾部窗口，展示出来，然后丢弃。&lt;/p&gt;
&lt;p&gt;开始 tail 只需要几个选择：选一个 &lt;strong&gt;Pod&lt;/strong&gt;（固定的服务实例）、一个 &lt;strong&gt;Container&lt;/strong&gt;（Horizon 会列出 pod 的容器并默认选第一个）、一个回看 &lt;strong&gt;Window&lt;/strong&gt;（last 30s、1m、5m、15m 或 30m，决定每次轮询向前取多远），以及轮询 &lt;strong&gt;Interval&lt;/strong&gt;（2s、5s、10s 或 30s，决定多久重新取一次）。按 &lt;strong&gt;Start&lt;/strong&gt; 后，日志会流入只读查看器，保持最新行可见，并持续轮询直到你按 &lt;strong&gt;Pause&lt;/strong&gt;。顶部状态条显示 container、行数、live 状态，以及上次更新距今多久。两行 &lt;strong&gt;Include&lt;/strong&gt; / &lt;strong&gt;Exclude&lt;/strong&gt; 过滤器用来收窄可见内容；每个标签都是一个 &lt;strong&gt;整行正则表达式&lt;/strong&gt;（&lt;code&gt;.*error.*&lt;/code&gt;），由 OAP 执行，所以它匹配整行而不是子串，并且可以叠加。&lt;/p&gt;
&lt;p&gt;使用前需要知道一点：按需读取 pod logs 在 OAP 上 &lt;strong&gt;默认关闭&lt;/strong&gt;，因为容器输出可能包含敏感信息。功能关闭时，或者你选择的 pod 已经滚动或缩容消失时，OAP 会返回一个 &lt;em&gt;原因&lt;/em&gt;，Horizon 会把它显示成横幅，而不是给你一个空面板。这样你能区分“需要打开这个功能”和“那个 pod 已经不存在”。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/screenshots/horizon-0.7.0/p07-logs-03-pod-logs.webp&#34; alt=&#34;图 3：Pod Logs 标签页。pod 和 container 选择器、回看窗口和轮询间隔、live-indicator 状态条、Include/Exclude 正则标签，以及流式展示容器最近输出的只读日志窗口。&#34;&gt;
图 3：一个 pod 容器的实时 tail：窗口化、按间隔轮询、可用正则过滤、永不持久化。&lt;/br&gt;&lt;/p&gt;
&lt;h2 id=&#34;后续阅读&#34;&gt;后续阅读&lt;/h2&gt;
&lt;p&gt;两个标签页，包括存储查询、tag/container 自动补全和 live tail，都由同一个 &lt;code&gt;logs:read&lt;/code&gt; 权限控制。所以授予“可以读日志”就是一个开关。字段参考，包括每个条件、histogram、Pod Logs 的窗口和过滤器，可以看 &lt;a href=&#34;https://skywalking.apache.org/docs/skywalking-horizon-ui/next/operate/logs/&#34;&gt;Logs 文档&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;下一篇看 &lt;a href=&#34;/zh/2026-06-23-horizon-ui-browser-errors-and-source-maps/&#34;&gt;Browser/RUM&lt;/a&gt;：浏览器端错误如何上报，又如何用 source map 把压缩后的 stack 还原到源码位置。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Zh: 认识 Horizon UI · 8/17：浏览器错误与 Source Map</title>
      <link>/zh/2026-06-23-horizon-ui-browser-errors-and-source-maps/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/zh/2026-06-23-horizon-ui-browser-errors-and-source-maps/</guid>
      <description>
        
        
        &lt;p&gt;&lt;em&gt;译自英文原文：&lt;a href=&#34;/blog/2026-06-23-horizon-ui-browser-errors-and-source-maps/&#34;&gt;Meet Horizon UI · 8/17: Browser Errors &amp;amp; Source Maps&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;这是 &lt;a href=&#34;/zh/2026-06-21-skywalking-horizon-ui-introduction/&#34;&gt;Meet Horizon UI&lt;/a&gt; 系列的第八篇。&lt;a href=&#34;/zh/2026-06-23-horizon-ui-log-explorer/&#34;&gt;第七篇&lt;/a&gt;讲的是服务日志；这一篇讲 &lt;em&gt;用户&lt;/em&gt; 遇到的错误，也就是浏览器端 agent 上报的 JavaScript 异常，以及把这些错误定位到源码的关键一步。&lt;/p&gt;
&lt;p&gt;生产环境 JavaScript stack 基本不可读。代码经过压缩和打包后发布，浏览器只会报告错误出现在 &lt;code&gt;app.min.js:1:98412&lt;/code&gt;，也就是一段机器生成代码里的位置，几乎不给你任何线索。Horizon 要做的是找到正确的 &lt;strong&gt;source map&lt;/strong&gt;，把 stack 里的每一帧映射回源码：原始文件、行、列、符号名，以及出错位置附近的代码片段。&lt;/p&gt;
&lt;h2 id=&#34;浏览器端错误流&#34;&gt;浏览器端错误流&lt;/h2&gt;
&lt;p&gt;在 &lt;strong&gt;BROWSER&lt;/strong&gt; Layer 上，&lt;strong&gt;Browser Logs&lt;/strong&gt; 标签页（屏幕上的标签名，专指 JavaScript 错误流）会列出浏览器端 agent 上报的内容。BROWSER Layer 会把槽位重命名成自己的语义：services 变成 &lt;strong&gt;Applications&lt;/strong&gt;，instances 变成 &lt;strong&gt;Versions&lt;/strong&gt;，endpoints 变成 &lt;strong&gt;Pages&lt;/strong&gt;。这个列表的阅读方式类似 &lt;a href=&#34;/zh/2026-06-23-horizon-ui-log-explorer/&#34;&gt;Log Explorer&lt;/a&gt;：可点击的 &lt;strong&gt;category&lt;/strong&gt; legend 带计数，density histogram 位于日志流之上。每一行都有时间、&lt;strong&gt;category&lt;/strong&gt;、page、app version 和错误消息；如果带有压缩后的 &lt;code&gt;line:col&lt;/code&gt;，也会显示成标记。&lt;/p&gt;
&lt;p&gt;排查方式和 trace/log 标签页一致：它使用独立的 &lt;strong&gt;Time range&lt;/strong&gt;（全局顶栏暂停），你可以按 &lt;strong&gt;Version&lt;/strong&gt;、&lt;strong&gt;Page&lt;/strong&gt; 或 &lt;strong&gt;Category&lt;/strong&gt; 收窄，然后点击 &lt;strong&gt;Run query&lt;/strong&gt;。没有后台轮询把视图不断往前推，也没有要学习的查询语言，只有结构化控件。点击一行后，它会在日志流里原地展开。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/screenshots/horizon-0.7.0/p08-browser-01-stream.webp&#34; alt=&#34;图 1：BROWSER Layer 上的 Browser Logs 标签页。category legend 和 density histogram 位于 JS 错误流上方，每行显示 category、page、app version 和压缩后的 line:col。&#34;&gt;
图 1：浏览器端 agent 上报的错误流：按 category 组织、带图表，并限定到某个 app 版本和页面。&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;压缩后的 &lt;code&gt;line:col&lt;/code&gt; 就是最典型的问题。它是真实位置，但位置在 &lt;em&gt;构建后&lt;/em&gt; 的 bundle 里，不在你的源码里。后面的解析流程就是为了解决这个落差。&lt;/p&gt;
&lt;h2 id=&#34;从压缩后的-stack-定位到源码&#34;&gt;从压缩后的 stack 定位到源码&lt;/h2&gt;
&lt;p&gt;展开一个错误后，面板分成两侧：左边是浏览器原样报告的 &lt;strong&gt;raw stack&lt;/strong&gt;，也就是那段很难读的生产栈；右边是解析结果区域。选择一个 &lt;strong&gt;source map&lt;/strong&gt;，点击 &lt;strong&gt;Resolve&lt;/strong&gt;，Horizon 会解析 stack，并通过这份 map 映射 &lt;strong&gt;每一帧&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每帧原始 &lt;strong&gt;&lt;code&gt;file:line:column&lt;/code&gt;&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;原始 &lt;strong&gt;symbol name&lt;/strong&gt;（如果 map 携带了）；&lt;/li&gt;
&lt;li&gt;出错行附近几行 &lt;strong&gt;原始源码&lt;/strong&gt;，命中行会高亮（如果 map 内嵌 &lt;code&gt;sourcesContent&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;map 覆盖不到的 frame 会明确标为 &lt;code&gt;unmapped&lt;/code&gt;。所以一条顶层 frame 为 &lt;code&gt;app.min.js:1:45&lt;/code&gt; 的 stack，可以还原成 &lt;code&gt;checkout.ts:2:20&lt;/code&gt; 上的 &lt;code&gt;computeCartTotal&lt;/code&gt;，并把 &lt;code&gt;checkout.ts&lt;/code&gt; 附近几行显示出来。真正抛错的 &lt;code&gt;cart.items.reduce(...)&lt;/code&gt; 就在面板里，不只是还原第一帧，而是从上到下还原整条 stack。&lt;/p&gt;
&lt;p&gt;这里有一些细节决定结果是否可信：浏览器 stack 的列号从 1 开始计数，source map 从 0 开始计数，所以解析器每次查找前都会做偏移；这条路径用真实 bundler 输出测试，而不是手写 fixture。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/screenshots/horizon-0.7.0/p08-browser-02-resolve.webp&#34; alt=&#34;图 2：展开后的错误。左侧是压缩后的原始 stack，右侧是解析后的 stack，每一帧显示原始 file:line:column、symbol 和高亮源码片段。&#34;&gt;
图 2：核心流程：把压缩后的 stack 匹配到正确 map，然后逐帧还原到你自己的源码。&lt;/br&gt;&lt;/p&gt;
&lt;h2 id=&#34;哪些错误可以用-source-map-解析&#34;&gt;哪些错误可以用 source map 解析&lt;/h2&gt;
&lt;p&gt;不是每类错误都有可还原内容。&lt;strong&gt;&lt;code&gt;JS&lt;/code&gt;&lt;/strong&gt;、&lt;strong&gt;&lt;code&gt;PROMISE&lt;/code&gt;&lt;/strong&gt; 和 &lt;strong&gt;&lt;code&gt;VUE&lt;/code&gt;&lt;/strong&gt; 是真实 JavaScript 错误，它们的 stack 指向 bundle，可以解析。&lt;strong&gt;&lt;code&gt;AJAX&lt;/code&gt;&lt;/strong&gt; 和 &lt;strong&gt;&lt;code&gt;RESOURCE&lt;/code&gt;&lt;/strong&gt; 是网络和加载失败；它们的“stack”是 HTTP status 或失败 URL，不是代码，所以 source map 没有东西可映射（Horizon 不会阻止它们，只是没有可映射的 JavaScript 位置）。没有 source map 的代码、&lt;code&gt;eval&lt;/code&gt; 或 inline scripts 里的 frame，也会保持 &lt;code&gt;unmapped&lt;/code&gt;。（&lt;code&gt;JS&lt;/code&gt; 也是唯一由浏览器上报顶层 &lt;code&gt;line:col&lt;/code&gt; 的 category；其他 category 的位置在 stack 字符串内部，由解析器提取。）&lt;/p&gt;
&lt;h2 id=&#34;提供-source-map上传或挂载&#34;&gt;提供 source map：上传或挂载&lt;/h2&gt;
&lt;p&gt;解析前必须让 map 可用。Horizon 提供两种方式，持久化策略有意不同：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Upload&lt;/strong&gt; 一个 &lt;code&gt;.map&lt;/code&gt;，直接从标签页上传。它只保存在服务端 &lt;strong&gt;内存&lt;/strong&gt; 里，没有后端存储，并且临时性是设计目标：它占用内存预算，在压力下按 least-recently-used 淘汰，&lt;strong&gt;服务重启后丢失&lt;/strong&gt;；多实例部署时，它也只存在于接收上传的那一个实例。这个路径适合临时排查：拖一个 map 进来，解析，处理完离开。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mount&lt;/strong&gt; &lt;code&gt;.map&lt;/code&gt; 文件到服务端 &lt;strong&gt;source-map 目录&lt;/strong&gt;（容器镜像中是 &lt;code&gt;/app/sourcemaps&lt;/code&gt;，可通过 &lt;code&gt;HORIZON_SOURCEMAPS_DIR&lt;/code&gt; 指定）。这些文件在启动时按 Source Map v3 校验，按需从磁盘读取（所以不占内存预算），重启后仍然存在，会自动重新加载，并且 &lt;strong&gt;不能从 UI 删除&lt;/strong&gt;。这是生产路径：把构建产物里的 map 文件放进镜像或挂载目录，它们就一直可用。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;管理器会显示每个 map 的来源（&lt;em&gt;uploaded · temporary&lt;/em&gt; 还是 &lt;em&gt;mounted · durable&lt;/em&gt;），以及当前内存预算使用量。预算配置，包括单文件上限和常驻上传总量上限，默认 64 MiB 和 512 MiB，位于 &lt;code&gt;horizon.yaml&lt;/code&gt; 的 &lt;code&gt;sourceMaps&lt;/code&gt; 块。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/screenshots/horizon-0.7.0/p08-browser-03-sourcemap-manager.webp&#34; alt=&#34;图 3：source-map 管理器。Upload .map 控件、内存预算条（这里是 0 B / 512 MB，max 64 MB/file）和已加载 maps；图中 map 是 Mounted 且 durable，所以不能在这里删除，uploaded maps 会显示为 temporary。&#34;&gt;
图 3：两种提供 map 的方式：upload 用于快速排查，mount 用于生产环境长期使用。&lt;/br&gt;&lt;/p&gt;
&lt;h2 id=&#34;map-必须手动选择&#34;&gt;map 必须手动选择&lt;/h2&gt;
&lt;p&gt;Horizon 刻意 &lt;strong&gt;不猜测&lt;/strong&gt;。浏览器端 agent 会上报 app &lt;strong&gt;version&lt;/strong&gt;，但不会上报精确的构建指纹，所以没有安全方法自动把一个错误匹配到某份 map。用错构建的 map 会给出非常自信、但完全错误的行号，比没有答案更糟。所以这里由你选择：挑选和这次错误对应构建的 map，并按版本给 map 清晰命名。（还有一个必须直说的注意点：source map 的 &lt;code&gt;sourcesContent&lt;/code&gt; 会包含你的原始源码，所以无论上传还是挂载，都要把 map 当成敏感内容，只放在可信服务器上。）&lt;/p&gt;
&lt;p&gt;手动选择 map 这件事，也划清了 &lt;strong&gt;权限&lt;/strong&gt; 边界。查看错误、列出 maps、&lt;strong&gt;解析&lt;/strong&gt; stack 都是读操作，由 &lt;code&gt;browser-errors:read&lt;/code&gt; 控制；&lt;strong&gt;上传或删除&lt;/strong&gt; map 是写操作，由 &lt;code&gt;source-map:write&lt;/code&gt; 控制。所以只读用户可以反复解析 stack，但没有权限改变已加载的 map 集合。读就是读，修改 map 存储才是写。&lt;/p&gt;
&lt;h2 id=&#34;后续阅读&#34;&gt;后续阅读&lt;/h2&gt;
&lt;p&gt;字段参考，包括 categories、两种提供路径、预算，以及如何按构建版本匹配 map，可以看 &lt;a href=&#34;https://skywalking.apache.org/docs/skywalking-horizon-ui/next/operate/browser-source-maps/&#34;&gt;Browser Logs &amp;amp; Source Maps 文档&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;下一篇进入 &lt;a href=&#34;/zh/2026-06-26-horizon-ui-profiling/&#34;&gt;Profiling&lt;/a&gt;：五种 profiler（trace、async、eBPF、Go pprof、network）如何共用一套火焰图视图，以及为什么 network profiling 是例外。&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Blog: Use of SkyWalking Go Toolkit Log and Metrics</title>
      <link>/blog/2024-10-20-skywalking-go-toolkit-metrics-log/</link>
      <pubDate>Sun, 20 Oct 2024 00:00:00 +0000</pubDate>
      <guid>/blog/2024-10-20-skywalking-go-toolkit-metrics-log/</guid>
      <description>
        
        
        &lt;h2 id=&#34;intro&#34;&gt;Intro&lt;/h2&gt;
&lt;p&gt;Apache SkyWalking Go is an observability tool specifically designed for Golang applications, aimed at monolithic services, microservices, cloud-native architectures, and containerized applications. It is the Go language implementation of the Apache SkyWalking probe project, providing comprehensive capabilities for service tracing, performance metrics analysis, and application topology analysis.&lt;/p&gt;
&lt;p&gt;SkyWalking Go leverages Go&amp;rsquo;s concurrency features to achieve efficient data collection and analysis. By inserting a minimal amount of probe code into the application during compilation using AST (Abstract Syntax Tree), it can capture service request and response data, as well as system runtime status information. By reporting this collected data, SkyWalking Go can generate detailed service call chain diagrams, helping developers understand the dependencies between services and the performance status of each service.&lt;/p&gt;
&lt;p&gt;SkyWalking Go currently provides the following three capabilities for users to manually report relevant information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Trace&lt;/li&gt;
&lt;li&gt;Metrics&lt;/li&gt;
&lt;li&gt;Log&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This document aims to guide users on how to manually report log entries and metrics using the toolkit. For information on how to report trace linkage information with the toolkit, please refer to the &lt;a href=&#34;https://skywalking.apache.org/zh/2023-10-18-skywalking-toolkit-trace/&#34;&gt;SkyWalking Go Toolkit Trace Detailed Explanation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Before diving deeper, you may want to check the &lt;a href=&#34;https://skywalking.apache.org/zh/2023-06-01-quick-start-with-skywalking-go-agent/&#34;&gt;SkyWalking Go Agent Quick Start Guide&lt;/a&gt; to learn how to use the SkyWalking Go Agent.&lt;/p&gt;
&lt;p&gt;The following sections will introduce how to use these interfaces in specific scenarios.&lt;/p&gt;
&lt;h2 id=&#34;import-trace-toolkit&#34;&gt;Import Trace Toolkit&lt;/h2&gt;
&lt;p&gt;First, execute the following command in the root directory of the project:&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;go get github.com/apache/skywalking-go/toolkit
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;manually-report-logs&#34;&gt;Manually report logs&lt;/h2&gt;
&lt;p&gt;In traceability, logs play a crucial role. They record detailed information about each request in the system, including timestamps, processing nodes, error messages, etc., which helps developers and operations teams quickly identify performance bottlenecks and the root causes of failures. By comparing logs from different requests, teams can analyze the flow of requests, optimize system architecture, and improve service response speed and stability.&lt;/p&gt;
&lt;p&gt;In the SkyWalking Go toolkit, manually reported logs will be &lt;strong&gt;attached to the current context Span&lt;/strong&gt;, allowing us to associate specific log information with particular spans.&lt;/p&gt;
&lt;p&gt;First, we need to import the toolkit log package:&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-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;github.com/apache/skywalking-go/toolkit/logging&amp;#34;&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;We can build a simple web service that determines the validity of a username based on the request parameters. When the userName parameter is invalid, we log an error using the logging.Error API. This log will be attached to the currently active Span in the context.&lt;/p&gt;
&lt;p&gt;When recording logs, we can also append keyValues to the log information using variadic parameters, making the log entries more descriptive.&lt;/p&gt;
&lt;p&gt;For detailed usage documentation, please refer to &lt;a href=&#34;https://skywalking.apache.org/docs/skywalking-go/next/en/advanced-features/manual-apis/toolkit-log/&#34;&gt;SkyWalking Go toolkit-logging&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-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;package&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;main&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:#cf222e&#34;&gt;import&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:#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:#0a3069&#34;&gt;&amp;#34;log&amp;#34;&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:#0a3069&#34;&gt;&amp;#34;net/http&amp;#34;&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;&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:#0a3069&#34;&gt;&amp;#34;github.com/apache/skywalking-go&amp;#34;&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:#0a3069&#34;&gt;&amp;#34;github.com/apache/skywalking-go/toolkit/logging&amp;#34;&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:#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&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;func&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;main&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:#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:#1f2328&#34;&gt;http&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;HandleFunc&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;/user&amp;#34;&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:#cf222e&#34;&gt;func&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;w&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;http&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;ResponseWriter&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;r&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;http&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;Request&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:#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:#1f2328&#34;&gt;userName&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;:=&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;URL&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;Query&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;().&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;Get&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;userName&amp;#34;&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:#cf222e&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;len&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;userName&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:#0550ae&#34;&gt;==&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;||&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;userName&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;!=&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;root&amp;#34;&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:#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:#57606a&#34;&gt;// Log an entry, which will be attached to the currently active Span in the context.&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:#57606a&#34;&gt;// We can append log tags using variadic parameters.&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:#1f2328&#34;&gt;logging&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;Error&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;deny user login&amp;#34;&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:#0a3069&#34;&gt;&amp;#34;userName&amp;#34;&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;userName&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:#1f2328&#34;&gt;w&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;WriteHeader&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;http&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;StatusUnauthorized&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:#cf222e&#34;&gt;return&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:#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&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:#1f2328&#34;&gt;w&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;WriteHeader&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;http&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;StatusAccepted&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:#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&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:#cf222e&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;err&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;:=&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;http&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;ListenAndServe&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;:8080&amp;#34;&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:#cf222e&#34;&gt;nil&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;err&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;!=&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;nil&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:#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:#1f2328&#34;&gt;log&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;Fatalln&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;server running by err:&amp;#34;&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;err&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:#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:#1f2328&#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;Then we enhance it using the SkyWalking &lt;code&gt;Go Agent&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-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go build -toolexec&lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;/path/go-agent&amp;#34;&lt;/span&gt; -a -o demo .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;./log_en.png&#34; alt=&#34;Log Screenshot&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;manually-reporting-metrics-information&#34;&gt;Manually reporting metrics information&lt;/h2&gt;
&lt;p&gt;Metrics are extremely important in traceability, as they provide quantitative analysis of system performance. By monitoring metrics such as request latency, throughput, and error rates, teams can identify performance bottlenecks and potential issues, allowing them to optimize system architecture and resource allocation. Combined with traceability, metrics can reveal the flow of requests between services, helping teams gain deeper insights into the health status and usage patterns of the system, ensuring high availability of services and a positive user experience, ultimately supporting business objectives effectively.&lt;/p&gt;
&lt;p&gt;The current toolkit metrics support the following types of metrics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Counter&lt;/li&gt;
&lt;li&gt;Gauge&lt;/li&gt;
&lt;li&gt;Histogram&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;First, execute the following command in the root directory of the project:&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-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;github.com/apache/skywalking-go/toolkit/metric&amp;#34;&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;We can build a simple Echo service that creates a Counter type metric to record the number of requests. At the same time, we can use metric.WithLabels to add additional labels to the metric.&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-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;package&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;main&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:#cf222e&#34;&gt;import&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:#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:#0a3069&#34;&gt;&amp;#34;log&amp;#34;&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:#0a3069&#34;&gt;&amp;#34;net/http&amp;#34;&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;&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:#0a3069&#34;&gt;&amp;#34;github.com/apache/skywalking-go&amp;#34;&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:#0a3069&#34;&gt;&amp;#34;github.com/apache/skywalking-go/toolkit/metric&amp;#34;&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:#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&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;func&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;main&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:#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:#57606a&#34;&gt;// Create a Counter type metric&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:#57606a&#34;&gt;// We also set labels for this Counter&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:#1f2328&#34;&gt;counter&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;:=&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;metric&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;NewCounter&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:#0a3069&#34;&gt;&amp;#34;http_request_count&amp;#34;&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:#1f2328&#34;&gt;metric&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;WithLabels&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;path&amp;#34;&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:#0a3069&#34;&gt;&amp;#34;/ping&amp;#34;&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:#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&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:#1f2328&#34;&gt;http&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;HandleFunc&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;/ping&amp;#34;&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:#cf222e&#34;&gt;func&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;w&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;http&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;ResponseWriter&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;r&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;http&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;Request&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:#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:#57606a&#34;&gt;// Increment the count by one for each incoming request&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:#1f2328&#34;&gt;counter&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;Inc&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;1&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&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:#1f2328&#34;&gt;w&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;WriteHeader&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;http&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;StatusOK&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:#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&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:#cf222e&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;err&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;:=&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;http&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;ListenAndServe&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;:8080&amp;#34;&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:#cf222e&#34;&gt;nil&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;err&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0550ae&#34;&gt;!=&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#cf222e&#34;&gt;nil&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:#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:#1f2328&#34;&gt;log&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;Fatalln&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;server running by err:&amp;#34;&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;err&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:#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:#1f2328&#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;Then we enhance it using the SkyWalking &lt;code&gt;Go Agent&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-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go build -toolexec&lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;/path/go-agent&amp;#34;&lt;/span&gt; -a -o demo .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can display the metric information in the &lt;a href=&#34;https://skywalking.apache.org/docs/main/next/en/ui/readme/#widget&#34;&gt;SkyWalking Custom Dashboard&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;summarize&#34;&gt;Summarize&lt;/h2&gt;
&lt;p&gt;This document discusses the basic usage of the Log APIs and Metrics APIs in SkyWalking Go. It provides users with the functionality to customize and report log entries and metric information.&lt;/p&gt;
&lt;p&gt;The SkyWalking Go toolkit was designed with simplicity in mind, aiming to shorten the distance between users and the product.&lt;/p&gt;
&lt;p&gt;For more information, please refer to &lt;a href=&#34;https://skywalking.apache.org/docs/skywalking-go/next/readme/&#34;&gt;SkyWalking Go&lt;/a&gt;.&lt;/p&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: New Features of SkyWalking Go 0.2.0</title>
      <link>/blog/2023-07-31-skywalking-go-0.2.0-release/</link>
      <pubDate>Mon, 31 Jul 2023 00:00:00 +0000</pubDate>
      <guid>/blog/2023-07-31-skywalking-go-0.2.0-release/</guid>
      <description>
        
        
        &lt;h1 id=&#34;announcing-apache-skywalking-go-020&#34;&gt;Announcing Apache SkyWalking Go 0.2.0&lt;/h1&gt;
&lt;p&gt;I&amp;rsquo;m excited to announce the release of Apache SkyWalking Go 0.2.0! This version packs several awesome new features that I&amp;rsquo;ll overview below.&lt;/p&gt;
&lt;h1 id=&#34;log-reporting&#34;&gt;Log Reporting&lt;/h1&gt;
&lt;p&gt;The log reporting feature allows the Go agent to automatically collect log content from supported logging frameworks like &lt;a href=&#34;https://github.com/sirupsen/logrus&#34;&gt;logrus&lt;/a&gt; and &lt;a href=&#34;https://pkg.go.dev/go.uber.org/zap&#34;&gt;zap&lt;/a&gt;.
The logs are organized and sent to the SkyWalking backend for visualization. You can see how the logs appear for each service in the SkyWalking UI:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;reported_logging.png&#34; alt=&#34;Reported Logging&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;making-logs-searchable&#34;&gt;Making Logs Searchable&lt;/h2&gt;
&lt;p&gt;You can configure certain log fields to make them searchable in SkyWalking. Set the &lt;code&gt;SW_AGENT_LOG_REPORTER_LABEL_KEYS&lt;/code&gt; environment variable to include additional fields beyond the default log level.&lt;/p&gt;
&lt;p&gt;For example, with logrus:&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-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f6f8fa;background-color:#82071e&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;define&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;log&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;with&lt;/span&gt;&lt;span style=&#34;color:#fff&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;fields&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:#1f2328&#34;&gt;logrus&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;WithField&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;module&amp;#34;&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:#0a3069&#34;&gt;&amp;#34;test-service&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;Info&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;test log&amp;#34;&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;metrics-reporting&#34;&gt;Metrics Reporting&lt;/h2&gt;
&lt;p&gt;The agent can now collect and report custom metrics data from &lt;code&gt;runtime/metrics&lt;/code&gt; to the backend. Supported metrics are documented &lt;a href=&#34;https://pkg.go.dev/runtime/metrics#hdr-Metric_key_format&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;metrics.png&#34; alt=&#34;Runtime Metrics&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;automatic-instrumentation&#34;&gt;Automatic Instrumentation&lt;/h1&gt;
&lt;p&gt;In 0.1.0, you had to manually integrate the agent into your apps. Now, the new commands can automatically analyze and instrument projects at a specified path, no code changes needed!
Try using the following command to import &lt;code&gt;skywalking-go&lt;/code&gt; into your project:&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 style=&#34;color:#57606a&#34;&gt;# inject to project at current path&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;skywalking-go-agent -inject&lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt;./ -all
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or you can still use the original manual &lt;a href=&#34;https://github.com/apache/skywalking-go/blob/main/docs/en/setup/gobuild.md#22-code-dependency&#34;&gt;approach&lt;/a&gt; if preferred.&lt;/p&gt;
&lt;h1 id=&#34;get-it-now&#34;&gt;Get It Now!&lt;/h1&gt;
&lt;p&gt;Check out the &lt;a href=&#34;https://skywalking.apache.org/events/release-apache-skwaylking-go-0.2.0/&#34;&gt;CHANGELOG&lt;/a&gt; for the full list of additions and fixes. I encourage you to try out SkyWalking Go 0.2.0 today! Let me know if you have any feedback.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Blog: SourceMarker: Continuous Feedback for Developers</title>
      <link>/blog/2021-03-16-continuous-feedback/</link>
      <pubDate>Tue, 16 Mar 2021 00:00:00 +0000</pubDate>
      <guid>/blog/2021-03-16-continuous-feedback/</guid>
      <description>
        
        
        &lt;p&gt;&lt;img src=&#34;SM_IDE-APM.gif&#34; alt=&#34;Alt Text&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://sourcemarker.dev&#34;&gt;SourceMarker&lt;/a&gt; is an open-source continuous feedback IDE plugin built on top of Apache SkyWalking, a popular open-source APM system with monitoring, tracing, and diagnosing capabilities for distributed software systems. SkyWalking, a truly holistic system, provides the means for automatically producing, storing, and querying software operation metrics. It requires little to no code changes to implement and is lightweight enough to be used in production. By itself, SkyWalking is a formidable force in the realm of continuous monitoring technology.&lt;/p&gt;
&lt;p&gt;SourceMarker, leveraging the continuous monitoring functionality provided by SkyWalking, creates continuous feedback technology by automatically linking software operation metrics to source code and displaying feedback directly inside of the IDE. While currently only supporting JetBrains-based IDEs and JVM-based programming languages, SourceMarker may be extended to support any number of programming languages and IDEs. Using SourceMarker, software developers can understand and validate software operation inside of their IDE. Instead of charts that indicate the health of the application, software developers can view the health of individual source code components and interpret software operation metrics from a much more familiar perspective. Such capabilities improve productivity as time spent continuously context switching from development to monitoring would be eliminated.&lt;/p&gt;
&lt;h2 id=&#34;logging&#34;&gt;Logging&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;SM_Logging.gif&#34; alt=&#34;Logging&#34;&gt;&lt;/p&gt;
&lt;p&gt;The benefits of continuous feedback technology are immediately apparent with the ability to view and search logs directly from source code. Instead of tailing log files or viewing logs through the browser, SourceMarker allows software developers to navigate production logs just as easily as they navigate source code. By using the source code as the primary perspective for navigating logs, SourceMarker allows software developers to view logs specific to any package, class, method, or line directly from the context of the source code which resulted in those logs.&lt;/p&gt;
&lt;h2 id=&#34;tracing&#34;&gt;Tracing&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;SM_Tracing.gif&#34; alt=&#34;Tracing&#34;&gt;&lt;/p&gt;
&lt;p&gt;Furthermore, continuous feedback technology offers software developers a deeper understanding of software by explicitly tying the implicit software operation to source code. Instead of visualizing software traces as Gantt charts, SourceMarker allows software developers to step through trace stacks while automatically resolving trace tags and logs. With SourceMarker, software developers can navigate production software traces in much the same way one debugs local applications.&lt;/p&gt;
&lt;h2 id=&#34;alerting&#34;&gt;Alerting&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;SM_Alerting.gif&#34; alt=&#34;Alerting&#34;&gt;&lt;/p&gt;
&lt;p&gt;Most importantly, continuous feedback technology keeps software developers aware of production software operation. Armed with an APM-powered IDE, every software developer can keep track of the behavior of any method, class, package, and even the entire application itself. Moreover, this allows for source code to be the medium through which production bugs are made evident, thereby creating the feasibility of source code with the ability to self-diagnose and convey its own health.&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id=&#34;download-sourcemarker&#34;&gt;Download SourceMarker&lt;/h1&gt;
&lt;p&gt;SourceMarker aims to bridge the theoretical and empirical practices of software development through continuous feedback. The goal is to make developing software with empirical data feel natural and intuitive, creating more complete software developers that understand the entire software development cycle.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/sourceplusplus/sourcemarker&#34;&gt;https://github.com/sourceplusplus/sourcemarker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This project is still early in its development, so if you think of any ways to improve SourceMarker, please let us know.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Blog: Apache SkyWalking 8.4: Logs, VM Monitoring, and Dynamic Configurations at Agent Side</title>
      <link>/blog/skywalking8-4-release/</link>
      <pubDate>Fri, 05 Feb 2021 00:00:00 +0000</pubDate>
      <guid>/blog/skywalking8-4-release/</guid>
      <description>
        
        
        &lt;p&gt;&lt;img src=&#34;heading.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Origin: &lt;a href=&#34;https://www.tetrate.io/blog/skywalking-8-4/&#34;&gt;Tetrate.io blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Apache SkyWalking team today announced the 8.4 release is generally available. This release fills the gap between all previous versions of SkyWalking and the logging domain area.
The release also advances SkyWalking’s capabilities  for infrastructure observability, starting with virtual machine monitoring.&lt;/p&gt;
&lt;h2 id=&#34;background&#34;&gt;Background&lt;/h2&gt;
&lt;p&gt;SkyWalking has historically focused on the tracing and metrics fields of observability.
As its features for tracing, metrics and service level monitoring have become more and more powerful and stable, the SkyWalking team has started to explore new scenarios covered by observability.
Because service performance is reflected in the logs, and is highly impacted by the infrastructure on which it runs, SkyWalking brings these two fields into the 8.4 release.
This release blog briefly introduces the two new features as well as some other notable changes.&lt;/p&gt;
&lt;h2 id=&#34;logs&#34;&gt;Logs&lt;/h2&gt;
&lt;p&gt;Metrics, tracing, and logging are considered the three pillars of observability [1]. SkyWalking had the full features of metrics and tracing prior to 8.4; today, as 8.4 is released, the last piece of the jigsaw is now in place.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;figure01.png&#34; alt=&#34;Logs Collected By SkyWalking&#34;&gt;
Figure 1: Logs Collected By SkyWalking&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;figure02.png&#34; alt=&#34;Logs Collected By SkyWalking&#34;&gt;
Figure 2: Logs Collected By SkyWalking&lt;/p&gt;
&lt;p&gt;The Java agent firstly provides SDKs to enhance the widely-used logging frameworks, log4j (1.x and 2.x) [2] and logback [3], and send the logs to the SkyWalking backend (OAP).
The latter is able to collect logs from wherever the protocol is  implemented.
This is not a big deal, but when it comes to the correlation between logs and traces, the traditional solution is to print the trace IDs in the logs, and pick the IDs in the error logs to query the related traces.
SkyWalking just simplifies the workflow by correlating the logs and traces natively. Navigating between traces and their related logs is as simple as clicking a button.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;figure03.png&#34; alt=&#34;Correlation Between Logs and Traces&#34;&gt;
Figure 3: Correlation Between Logs and Traces&lt;/p&gt;
&lt;h2 id=&#34;infrastructure-monitoring&#34;&gt;Infrastructure Monitoring&lt;/h2&gt;
&lt;p&gt;SkyWalking is known as an application performance monitoring tool. One of the most important factors that impacts the application’s performance is the infrastructure on which the application runs.
In the 8.4 release, we added the monitoring metrics of virtual machines into the dashboard.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;figure04.png&#34; alt=&#34;VM Metrics&#34;&gt;
Figure 4: VM Metrics&lt;/p&gt;
&lt;p&gt;Fundamental metrics such as &lt;code&gt;CPU Used&lt;/code&gt;, &lt;code&gt;Memory Used&lt;/code&gt;,  &lt;code&gt;Disk Read / Write&lt;/code&gt; and &lt;code&gt;Network Usage&lt;/code&gt; are available on the dashboard.
And as usual, those metrics are also available to be configured as alarm triggers when needed.&lt;/p&gt;
&lt;h2 id=&#34;dynamic-configurations-at-agent-side&#34;&gt;Dynamic Configurations at Agent Side&lt;/h2&gt;
&lt;p&gt;Dynamic configuration at the backend side has long existed in SkyWalking for several versions. Now, it finally comes to the agent side!
Prior to 8.4, you’d have to restart the target services when you modify some configuration items of the agent &amp;ndash; for instance, sampling rate (agent side), ignorable endpoint paths, etc. Now, say goodbye to rebooting.
Modifying configurations is not the only usage of the dynamic configuration mechanism. The latter gives countless possibilities to the agent side in terms of dynamic behaviours, e.g. enabling / disabling plugins, enabling / disabling the whole agent, etc. Just imagine!&lt;/p&gt;
&lt;h2 id=&#34;grouped-service-topology&#34;&gt;Grouped Service Topology&lt;/h2&gt;
&lt;p&gt;This enhancement is from the UI. SkyWalking backend supports grouping the services by user-defined dimensions. In a real world use case, the services are usually grouped by business group or department. When a developer opens the topology map, out of hundreds of services, he or she may just want to focus on the services in charge. The grouped service topology comes to the rescue: one can now choose to display only services belonging to a specified group.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;figure05.png&#34; alt=&#34;Grouped Service Topology&#34;&gt;
Figure 5: Grouped Service Topology&lt;/p&gt;
&lt;h2 id=&#34;other-notable-enhancements&#34;&gt;Other Notable Enhancements&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Agent: resolves domain names to look up backend service IP addresses.&lt;/li&gt;
&lt;li&gt;Backend: meter receiver supports meter analysis language (MAL).&lt;/li&gt;
&lt;li&gt;Backend: several CVE fixes.&lt;/li&gt;
&lt;li&gt;Backend: supports Envoy &lt;code&gt;{AccessLog,Metrics}Service&lt;/code&gt; API V3 and adopts MAL.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;links&#34;&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[1] &lt;a href=&#34;https://peter.bourgon.org/blog/2017/02/21/metrics-tracing-and-logging.html&#34;&gt;https://peter.bourgon.org/blog/2017/02/21/metrics-tracing-and-logging.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2] &lt;a href=&#34;https://logging.apache.org/log4j/2.x/&#34;&gt;https://logging.apache.org/log4j/2.x/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[3] &lt;a href=&#34;http://logback.qos.ch&#34;&gt;http://logback.qos.ch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;additional-resources&#34;&gt;Additional Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Read more about the &lt;a href=&#34;https://github.com/apache/skywalking/blob/v8.4.0/changes/changes-8.4.0.md&#34;&gt;SkyWalking 8.4 release highlights&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Get more SkyWalking updates on &lt;a href=&#34;https://twitter.com/ASFSkyWalking&#34;&gt;Twitter&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

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