277 lines
15 KiB
Plaintext
Generated
277 lines
15 KiB
Plaintext
Generated
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Go by Example: Logging</title>
|
|
<link rel=stylesheet href="site.css">
|
|
</head>
|
|
<script>
|
|
onkeydown = (e) => {
|
|
|
|
if (e.key == "ArrowLeft") {
|
|
window.location.href = 'environment-variables';
|
|
}
|
|
|
|
|
|
if (e.key == "ArrowRight") {
|
|
window.location.href = 'http-client';
|
|
}
|
|
|
|
}
|
|
</script>
|
|
<body>
|
|
<div class="example" id="logging">
|
|
<h2><a href="./">Go by Example</a>: Logging</h2>
|
|
|
|
<table>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>The Go standard library provides straightforward
|
|
tools for outputting logs from Go programs, with
|
|
the <a href="https://pkg.go.dev/log">log</a> package for
|
|
free-form output and the
|
|
<a href="https://pkg.go.dev/log/slog">log/slog</a> package for
|
|
structured output.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
<a href="https://go.dev/play/p/Qd0uCqBlYUn"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
|
|
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
|
|
</span></span><span class="line"><span class="cl"> <span class="s">"bytes"</span>
|
|
</span></span><span class="line"><span class="cl"> <span class="s">"fmt"</span>
|
|
</span></span><span class="line"><span class="cl"> <span class="s">"log"</span>
|
|
</span></span><span class="line"><span class="cl"> <span class="s">"os"</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="s">"log/slog"</span>
|
|
</span></span><span class="line"><span class="cl"><span class="p">)</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>Simply invoking functions like <code>Println</code> from the
|
|
<code>log</code> package uses the <em>standard</em> logger, which
|
|
is already pre-configured for reasonable logging
|
|
output to <code>os.Stderr</code>. Additional methods like
|
|
<code>Fatal*</code> or <code>Panic*</code> will exit the program after
|
|
logging.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">"standard logger"</span><span class="p">)</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>Loggers can be configured with <em>flags</em> to set
|
|
their output format. By default, the standard
|
|
logger has the <code>log.Ldate</code> and <code>log.Ltime</code> flags
|
|
set, and these are collected in <code>log.LstdFlags</code>.
|
|
We can change its flags to emit time with
|
|
microsecond accuracy, for example.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">SetFlags</span><span class="p">(</span><span class="nx">log</span><span class="p">.</span><span class="nx">LstdFlags</span> <span class="p">|</span> <span class="nx">log</span><span class="p">.</span><span class="nx">Lmicroseconds</span><span class="p">)</span>
|
|
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">"with micro"</span><span class="p">)</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>It also supports emitting the file name and
|
|
line from which the <code>log</code> function is called.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">SetFlags</span><span class="p">(</span><span class="nx">log</span><span class="p">.</span><span class="nx">LstdFlags</span> <span class="p">|</span> <span class="nx">log</span><span class="p">.</span><span class="nx">Lshortfile</span><span class="p">)</span>
|
|
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">"with file/line"</span><span class="p">)</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>It may be useful to create a custom logger and
|
|
pass it around. When creating a new logger, we
|
|
can set a <em>prefix</em> to distinguish its output
|
|
from other loggers.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">mylog</span> <span class="o">:=</span> <span class="nx">log</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stdout</span><span class="p">,</span> <span class="s">"my:"</span><span class="p">,</span> <span class="nx">log</span><span class="p">.</span><span class="nx">LstdFlags</span><span class="p">)</span>
|
|
</span></span><span class="line"><span class="cl"> <span class="nx">mylog</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">"from mylog"</span><span class="p">)</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>We can set the prefix
|
|
on existing loggers (including the standard one)
|
|
with the <code>SetPrefix</code> method.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">mylog</span><span class="p">.</span><span class="nf">SetPrefix</span><span class="p">(</span><span class="s">"ohmy:"</span><span class="p">)</span>
|
|
</span></span><span class="line"><span class="cl"> <span class="nx">mylog</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">"from mylog"</span><span class="p">)</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>Loggers can have custom output targets;
|
|
any <code>io.Writer</code> works.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">buf</span> <span class="nx">bytes</span><span class="p">.</span><span class="nx">Buffer</span>
|
|
</span></span><span class="line"><span class="cl"> <span class="nx">buflog</span> <span class="o">:=</span> <span class="nx">log</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="o">&</span><span class="nx">buf</span><span class="p">,</span> <span class="s">"buf:"</span><span class="p">,</span> <span class="nx">log</span><span class="p">.</span><span class="nx">LstdFlags</span><span class="p">)</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>This call writes the log output into <code>buf</code>.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">buflog</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">"hello"</span><span class="p">)</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>This will actually show it on standard output.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Print</span><span class="p">(</span><span class="s">"from buflog:"</span><span class="p">,</span> <span class="nx">buf</span><span class="p">.</span><span class="nf">String</span><span class="p">())</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>The <code>slog</code> package provides
|
|
<em>structured</em> log output. For example, logging
|
|
in JSON format is straightforward.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">jsonHandler</span> <span class="o">:=</span> <span class="nx">slog</span><span class="p">.</span><span class="nf">NewJSONHandler</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stderr</span><span class="p">,</span> <span class="kc">nil</span><span class="p">)</span>
|
|
</span></span><span class="line"><span class="cl"> <span class="nx">myslog</span> <span class="o">:=</span> <span class="nx">slog</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="nx">jsonHandler</span><span class="p">)</span>
|
|
</span></span><span class="line"><span class="cl"> <span class="nx">myslog</span><span class="p">.</span><span class="nf">Info</span><span class="p">(</span><span class="s">"hi there"</span><span class="p">)</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>In addition to the message, <code>slog</code> output can
|
|
contain an arbitrary number of key=value
|
|
pairs.</p>
|
|
|
|
</td>
|
|
<td class="code">
|
|
|
|
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">myslog</span><span class="p">.</span><span class="nf">Info</span><span class="p">(</span><span class="s">"hello again"</span><span class="p">,</span> <span class="s">"key"</span><span class="p">,</span> <span class="s">"val"</span><span class="p">,</span> <span class="s">"age"</span><span class="p">,</span> <span class="mi">25</span><span class="p">)</span>
|
|
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
<table>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>Sample output; the date and time
|
|
emitted will depend on when the example ran.</p>
|
|
|
|
</td>
|
|
<td class="code leading">
|
|
|
|
<pre class="chroma"><code><span class="line"><span class="cl"><span class="gp">$</span> go run logging.go
|
|
</span></span><span class="line"><span class="cl"><span class="go">2023/08/22 10:45:16 standard logger
|
|
</span></span></span><span class="line"><span class="cl"><span class="go">2023/08/22 10:45:16.904141 with micro
|
|
</span></span></span><span class="line"><span class="cl"><span class="go">2023/08/22 10:45:16 logging.go:40: with file/line
|
|
</span></span></span><span class="line"><span class="cl"><span class="go">my:2023/08/22 10:45:16 from mylog
|
|
</span></span></span><span class="line"><span class="cl"><span class="go">ohmy:2023/08/22 10:45:16 from mylog
|
|
</span></span></span><span class="line"><span class="cl"><span class="go">from buflog:buf:2023/08/22 10:45:16 hello</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="docs">
|
|
<p>These are wrapped for clarity of presentation
|
|
on the website; in reality they are emitted
|
|
on a single line.</p>
|
|
|
|
</td>
|
|
<td class="code">
|
|
|
|
<pre class="chroma"><code><span class="line"><span class="cl"><span class="go">{"time":"2023-08-22T10:45:16.904166391-07:00",
|
|
</span></span></span><span class="line"><span class="cl"><span class="go"> "level":"INFO","msg":"hi there"}
|
|
</span></span></span><span class="line"><span class="cl"><span class="go">{"time":"2023-08-22T10:45:16.904178985-07:00",
|
|
</span></span></span><span class="line"><span class="cl"><span class="go"> "level":"INFO","msg":"hello again",
|
|
</span></span></span><span class="line"><span class="cl"><span class="go"> "key":"val","age":25}</span></span></span></code></pre>
|
|
</td>
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
|
|
<p class="next">
|
|
Next example: <a href="http-client">HTTP Client</a>.
|
|
</p>
|
|
|
|
|
|
<p class="footer">
|
|
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> and <a href="https://eli.thegreenplace.net">Eli Bendersky</a> | <a href="https://github.com/mmcgrana/gobyexample">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>
|
|
</p>
|
|
|
|
</div>
|
|
<script>
|
|
var codeLines = [];
|
|
codeLines.push('package main\u000A');codeLines.push('import (\u000A \"bytes\"\u000A \"fmt\"\u000A \"log\"\u000A \"os\"\u000A');codeLines.push(' \"log/slog\"\u000A)\u000A');codeLines.push('func main() {\u000A');codeLines.push(' log.Println(\"standard logger\")\u000A');codeLines.push(' log.SetFlags(log.LstdFlags | log.Lmicroseconds)\u000A log.Println(\"with micro\")\u000A');codeLines.push(' log.SetFlags(log.LstdFlags | log.Lshortfile)\u000A log.Println(\"with file/line\")\u000A');codeLines.push(' mylog :\u003D log.New(os.Stdout, \"my:\", log.LstdFlags)\u000A mylog.Println(\"from mylog\")\u000A');codeLines.push(' mylog.SetPrefix(\"ohmy:\")\u000A mylog.Println(\"from mylog\")\u000A');codeLines.push(' var buf bytes.Buffer\u000A buflog :\u003D log.New(\u0026buf, \"buf:\", log.LstdFlags)\u000A');codeLines.push(' buflog.Println(\"hello\")\u000A');codeLines.push(' fmt.Print(\"from buflog:\", buf.String())\u000A');codeLines.push(' jsonHandler :\u003D slog.NewJSONHandler(os.Stderr, nil)\u000A myslog :\u003D slog.New(jsonHandler)\u000A myslog.Info(\"hi there\")\u000A');codeLines.push(' myslog.Info(\"hello again\", \"key\", \"val\", \"age\", 25)\u000A}\u000A');codeLines.push('');codeLines.push('');
|
|
</script>
|
|
<script src="site.js" async></script>
|
|
</body>
|
|
</html>
|