[インデックス 18041] ファイルの概要
このコミットは、Go言語の標準ライブラリであるlog
パッケージに新しいテスト例を追加するものです。具体的には、log.Logger
の基本的な使用方法を示すExampleLogger
関数がsrc/pkg/log/example_test.go
ファイルに追加されました。
コミット
commit 8c530becaf55ce3285121d0bf640085520ac3a4b
Author: ChaiShushan <chaishushan@gmail.com>
Date: Wed Dec 18 16:24:11 2013 +1100
log: add example
Fixes #6028.
R=golang-dev, bradfitz, adg, r
CC=golang-dev
https://golang.org/cl/43320043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/8c530becaf55ce3285121d0bf640085520ac3a4b
元コミット内容
log: add example
Fixes #6028.
R=golang-dev, bradfitz, adg, r
CC=golang-dev
https://golang.org/cl/43320043
変更の背景
このコミットは、Go言語のIssue 6028「log
パッケージに例を追加する」に対応するものです。Go言語の標準ライブラリは、その機能の理解と適切な使用を促進するために、豊富なドキュメントとコード例を提供することが推奨されています。特に、log
パッケージのような基本的なユーティリティは、開発者がログ出力のベストプラクティスを学ぶ上で、具体的なコード例が非常に役立ちます。
このコミット以前は、log
パッケージのドキュメントには、log.New
関数を使用してカスタムロガーを作成し、その出力先やフォーマットを制御する方法を示す具体的な例が不足していた可能性があります。そのため、開発者がlog
パッケージの柔軟性を十分に活用するためには、より実践的なコード例が必要とされていました。このコミットは、そのギャップを埋め、log
パッケージの利用方法をより明確にすることを目的としています。
前提知識の解説
Go言語のlog
パッケージ
Go言語の標準ライブラリには、基本的なロギング機能を提供するlog
パッケージが含まれています。このパッケージは、アプリケーションのイベント、エラー、デバッグ情報などを標準出力、ファイル、またはその他のI/Oライターに出力するために使用されます。
- デフォルトロガー:
log
パッケージは、log.Print
,log.Printf
,log.Println
,log.Fatal
,log.Fatalf
,log.Fatalln
,log.Panic
,log.Panicf
,log.Panicln
などの関数を通じて、すぐに使用できるデフォルトロガーを提供します。これらは通常、標準エラー出力にログを出力します。 - カスタムロガー:
log.New
関数を使用することで、開発者は独自のロガーインスタンスを作成できます。これにより、ログの出力先(io.Writer
インターフェースを実装する任意の型)、ログメッセージのプレフィックス、およびログフラグ(タイムスタンプ、ファイル名、行番号など)を細かく制御できます。
io.Writer
インターフェース
Go言語のio
パッケージは、I/O操作のための基本的なインターフェースを定義しています。io.Writer
インターフェースは、データを書き込むための単一のWrite
メソッドを持つインターフェースです。
type Writer interface {
Write(p []byte) (n int, err error)
}
log.New
関数は、このio.Writer
インターフェースを実装する任意のオブジェクトをログの出力先として受け取ります。これにより、ログを標準出力、ファイル、ネットワーク接続、またはメモリ上のバッファなど、様々な場所に柔軟に出力することが可能になります。
bytes.Buffer
bytes
パッケージのBuffer
型は、可変長のバイトバッファを実装しており、io.Writer
インターフェースを満たします。これは、データをメモリ上に一時的に蓄積するために非常に便利です。テストコードでは、ログ出力をファイルや標準出力に直接書き出す代わりに、bytes.Buffer
に書き出すことで、その内容をプログラム内で簡単に検証できるようになります。
log
パッケージのフラグ
log
パッケージは、ログメッセージに含める追加情報を制御するための様々なフラグを提供します。これらはビットマスクとして定義されており、log.New
関数やlog.SetFlags
関数に渡すことで設定できます。
log.Ldate
: ローカルタイムゾーンでの日付(例: 2009/01/23)log.Ltime
: ローカルタイムゾーンでの時刻(例: 01:23:23)log.Lmicroseconds
: 時刻にマイクロ秒の分解能を追加(例: 01:23:23.123123)log.Llongfile
: 完全なファイル名と行番号(例: /a/b/c/d.go:23)log.Lshortfile
: 最後のパス要素と行番号(例: d.go:23)。ログメッセージの生成元を特定するのに便利です。log.LUTC
: 日付と時刻をUTCで表示log.LstdFlags
:Ldate
とLtime
の組み合わせ
このコミットでは、log.Lshortfile
フラグが使用されており、ログメッセージにファイル名と行番号が含まれるようになります。
Go言語のテストとExample
関数
Go言語のテストフレームワークは、_test.go
ファイルに記述されたテスト関数を自動的に発見し実行します。Goのテストには、ユニットテスト、ベンチマークテスト、そしてExample
テストの3種類があります。
Example
テスト:Example
関数は、コードの動作例を示すために使用されます。これらの関数は、通常のテスト関数と同様にgo test
コマンドによって実行されますが、その目的はコードの動作を検証することよりも、ドキュメントとして機能することにあります。Example
関数の特別な機能として、関数内のコメントに// Output:
というプレフィックスを付けて期待される出力を記述することができます。go test
は、実際に実行された関数の出力とこの// Output:
コメントの内容を比較し、一致しない場合はテストを失敗させます。これにより、コード例が常に最新かつ正確であることを保証できます。また、go doc
コマンドでパッケージのドキュメントを生成する際に、Example
関数の内容が自動的にドキュメントに組み込まれるため、非常に効果的なドキュメンテーションツールとなります。
技術的詳細
このコミットは、log
パッケージのExampleLogger
関数をsrc/pkg/log/example_test.go
という新しいファイルに追加します。このファイルは、Goのテスト規約に従い、log_test
パッケージに属しています。これは、テスト対象のパッケージ(log
)とは異なるパッケージにテストを配置することで、外部からパッケージを使用する際の挙動をテストする「外部テスト」の形式を取っていることを意味します。
ExampleLogger
関数は、以下のステップでlog.Logger
の基本的な使用方法を示しています。
bytes.Buffer
の初期化:var buf bytes.Buffer
によって、ログメッセージを書き込むためのメモリ上のバッファが作成されます。これにより、ログ出力を標準出力に直接書き出すことなく、プログラム内でその内容をキャプチャし、検証することが可能になります。log.New
によるロガーの作成:logger := log.New(&buf, "logger: ", log.Lshortfile)
という行で、新しいlog.Logger
インスタンスが作成されます。- 第一引数
&buf
は、ログの出力先として先ほど作成したbytes.Buffer
のアドレスを渡しています。 - 第二引数
"logger: "
は、各ログメッセージの前に付加されるプレフィックスです。 - 第三引数
log.Lshortfile
は、ログメッセージにログを呼び出したソースファイル名と行番号を含めるためのフラグです。
- 第一引数
- ログメッセージの出力:
logger.Print("Hello, log file!")
によって、作成したロガーインスタンスを使用してログメッセージが出力されます。このメッセージはbuf
に書き込まれます。 - バッファの内容の出力:
fmt.Print(&buf)
によって、buf
に蓄積されたログメッセージが標準出力に書き出されます。これは、Example
テストの// Output:
コメントと比較するために必要です。 - 期待される出力の定義:
// Output:
コメントブロックは、このExample
関数が実行されたときに期待される正確な出力を定義しています。logger: example_test.go:15: Hello, log file!
- この出力は、設定されたプレフィックス(
logger:
)、ファイル名と行番号(example_test.go:15:
)、そして実際のログメッセージ(Hello, log file!
)が結合されたものです。行番号15
は、logger.Print
が呼び出されたexample_test.go
内の行番号に対応します。
このExample
関数は、go test
実行時に自動的にテストされ、その出力が// Output:
コメントと一致することが検証されます。これにより、log.New
の基本的な挙動と、log.Lshortfile
フラグの効果が明確に示され、ドキュメントとしても機能します。
コアとなるコードの変更箇所
src/pkg/log/example_test.go
という新しいファイルが追加され、以下の内容が記述されています。
--- /dev/null
+++ b/src/pkg/log/example_test.go
@@ -0,0 +1,21 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package log_test
+
+import (
+ "bytes"
+ "fmt"
+ "log"
+)
+
+func ExampleLogger() {
+ var buf bytes.Buffer
+ logger := log.New(&buf, "logger: ", log.Lshortfile)
+ logger.Print("Hello, log file!")
+
+ fmt.Print(&buf)
+ // Output:
+ // logger: example_test.go:15: Hello, log file!
+}
コアとなるコードの解説
追加されたExampleLogger
関数は、log
パッケージのカスタムロガーの作成と使用方法を簡潔に示しています。
package log_test
: この行は、このファイルがlog
パッケージの外部テストであることを示します。これにより、log
パッケージの公開されたAPIのみがテストされ、パッケージの内部実装に依存しないテストが保証されます。import
ブロック:"bytes"
:bytes.Buffer
を使用するためにインポートされます。"fmt"
:fmt.Print
を使用してバッファの内容を標準出力に書き出すためにインポートされます。"log"
: テスト対象のlog
パッケージ自体をインポートします。
func ExampleLogger()
: この関数は、Goのテストフレームワークによって特別なExample
テストとして認識されます。var buf bytes.Buffer
: ログメッセージをキャプチャするためのbytes.Buffer
インスタンスを宣言します。logger := log.New(&buf, "logger: ", log.Lshortfile)
:log.New
を呼び出して新しいロガーを作成します。&buf
: ログの出力先としてbuf
のアドレスを渡します。これにより、logger.Print
が呼び出されたときに、メッセージはbuf
に書き込まれます。"logger: "
: ログメッセージのプレフィックスを設定します。log.Lshortfile
: ログメッセージに、ログ呼び出し元のファイル名と行番号(例:example_test.go:15:
)を含めるように設定します。
logger.Print("Hello, log file!")
: 作成したロガーを使用して、指定された文字列をログに出力します。この出力はbuf
に格納されます。fmt.Print(&buf)
:buf
に蓄積されたすべての内容を標準出力に書き出します。これは、Example
テストの// Output:
コメントとの比較のために必要です。// Output:
コメント: この特別なコメントは、ExampleLogger
関数が実行されたときに期待される正確な出力を定義します。go test
コマンドは、実際の出力とこのコメントの内容を比較し、一致しない場合はテストを失敗させます。これにより、コード例が常に正しく、ドキュメントとして機能することが保証されます。
このコードは、log.New
の柔軟性、特にカスタム出力先とフラグの設定能力を明確に示しており、log
パッケージのドキュメントを補完する重要な役割を果たします。
関連リンク
- Go Issue 6028: log: add example
- Go Code Review CL 43320043: log: add example
参考にした情報源リンク
- Go言語
log
パッケージ公式ドキュメント: https://pkg.go.dev/log - Go言語
bytes
パッケージ公式ドキュメント: https://pkg.go.dev/bytes - Go言語
io
パッケージ公式ドキュメント: https://pkg.go.dev/io - Go言語のテストに関する公式ドキュメント(
Example
関数について): https://go.dev/blog/examples - Go言語のテストの書き方: https://go.dev/doc/tutorial/add-a-test
- Go言語の
go test
コマンド: https://go.dev/cmd/go/#hdr-Test_packages - Go言語の
go doc
コマンド: https://go.dev/cmd/go/#hdr-Show_documentation_for_package_or_symbol - Go言語の
log
パッケージのフラグに関する情報: https://pkg.go.dev/log#pkg-constants - Go言語の
io.Writer
インターフェースに関する情報: https://pkg.go.dev/io#Writer - Go言語の
bytes.Buffer
に関する情報: https://pkg.go.dev/bytes#Buffer - Go言語の
fmt
パッケージに関する情報: https://pkg.go.dev/fmt - Go言語の
package_test
とpackage
の違い: https://go.dev/doc/code#TestPackages - Go言語の
go test
における// Output:
の利用: https://go.dev/blog/examples# [インデックス 18041] ファイルの概要
このコミットは、Go言語の標準ライブラリであるlog
パッケージに新しいテスト例を追加するものです。具体的には、log.Logger
の基本的な使用方法を示すExampleLogger
関数がsrc/pkg/log/example_test.go
ファイルに追加されました。
コミット
commit 8c530becaf55ce3285121d0bf640085520ac3a4b
Author: ChaiShushan <chaishushan@gmail.com>
Date: Wed Dec 18 16:24:11 2013 +1100
log: add example
Fixes #6028.
R=golang-dev, bradfitz, adg, r
CC=golang-dev
https://golang.org/cl/43320043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/8c530becaf55ce3285121d0bf640085520ac3a4b
元コミット内容
log: add example
Fixes #6028.
R=golang-dev, bradfitz, adg, r
CC=golang-dev
https://golang.org/cl/43320043
変更の背景
このコミットは、Go言語のIssue 6028「log
パッケージに例を追加する」に対応するものです。Go言語の標準ライブラリは、その機能の理解と適切な使用を促進するために、豊富なドキュメントとコード例を提供することが推奨されています。特に、log
パッケージのような基本的なユーティリティは、開発者がログ出力のベストプラクティスを学ぶ上で、具体的なコード例が非常に役立ちます。
このコミット以前は、log
パッケージのドキュメントには、log.New
関数を使用してカスタムロガーを作成し、その出力先やフォーマットを制御する方法を示す具体的な例が不足していた可能性があります。そのため、開発者がlog
パッケージの柔軟性を十分に活用するためには、より実践的なコード例が必要とされていました。このコミットは、そのギャップを埋め、log
パッケージの利用方法をより明確にすることを目的としています。
前提知識の解説
Go言語のlog
パッケージ
Go言語の標準ライブラリには、基本的なロギング機能を提供するlog
パッケージが含まれています。このパッケージは、アプリケーションのイベント、エラー、デバッグ情報などを標準出力、ファイル、またはその他のI/Oライターに出力するために使用されます。
- デフォルトロガー:
log
パッケージは、log.Print
,log.Printf
,log.Println
,log.Fatal
,log.Fatalf
,log.Fatalln
,log.Panic
,log.Panicf
,log.Panicln
などの関数を通じて、すぐに使用できるデフォルトロガーを提供します。これらは通常、標準エラー出力にログを出力します。 - カスタムロガー:
log.New
関数を使用することで、開発者は独自のロガーインスタンスを作成できます。これにより、ログの出力先(io.Writer
インターフェースを実装する任意の型)、ログメッセージのプレフィックス、およびログフラグ(タイムスタンプ、ファイル名、行番号など)を細かく制御できます。
io.Writer
インターフェース
Go言語のio
パッケージは、I/O操作のための基本的なインターフェースを定義しています。io.Writer
インターフェースは、データを書き込むための単一のWrite
メソッドを持つインターフェースです。
type Writer interface {
Write(p []byte) (n int, err error)
}
log.New
関数は、このio.Writer
インターフェースを実装する任意のオブジェクトをログの出力先として受け取ります。これにより、ログを標準出力、ファイル、ネットワーク接続、またはメモリ上のバッファなど、様々な場所に柔軟に出力することが可能になります。
bytes.Buffer
bytes
パッケージのBuffer
型は、可変長のバイトバッファを実装しており、io.Writer
インターフェースを満たします。これは、データをメモリ上に一時的に蓄積するために非常に便利です。テストコードでは、ログ出力をファイルや標準出力に直接書き出す代わりに、bytes.Buffer
に書き出すことで、その内容をプログラム内で簡単に検証できるようになります。
log
パッケージのフラグ
log
パッケージは、ログメッセージに含める追加情報を制御するための様々なフラグを提供します。これらはビットマスクとして定義されており、log.New
関数やlog.SetFlags
関数に渡すことで設定できます。
log.Ldate
: ローカルタイムゾーンでの日付(例: 2009/01/23)log.Ltime
: ローカルタイムゾーンでの時刻(例: 01:23:23)log.Lmicroseconds
: 時刻にマイクロ秒の分解能を追加(例: 01:23:23.123123)log.Llongfile
: 完全なファイル名と行番号(例: /a/b/c/d.go:23)log.Lshortfile
: 最後のパス要素と行番号(例: d.go:23)。ログメッセージの生成元を特定するのに便利です。log.LUTC
: 日付と時刻をUTCで表示log.LstdFlags
:Ldate
とLtime
の組み合わせ
このコミットでは、log.Lshortfile
フラグが使用されており、ログメッセージにファイル名と行番号が含まれるようになります。
Go言語のテストとExample
関数
Go言語のテストフレームワークは、_test.go
ファイルに記述されたテスト関数を自動的に発見し実行します。Goのテストには、ユニットテスト、ベンチマークテスト、そしてExample
テストの3種類があります。
Example
テスト:Example
関数は、コードの動作例を示すために使用されます。これらの関数は、通常のテスト関数と同様にgo test
コマンドによって実行されますが、その目的はコードの動作を検証することよりも、ドキュメントとして機能することにあります。Example
関数の特別な機能として、関数内のコメントに// Output:
というプレフィックスを付けて期待される出力を記述することができます。go test
は、実際に実行された関数の出力とこの// Output:
コメントの内容を比較し、一致しない場合はテストを失敗させます。これにより、コード例が常に最新かつ正確であることを保証できます。また、go doc
コマンドでパッケージのドキュメントを生成する際に、Example
関数の内容が自動的にドキュメントに組み込まれるため、非常に効果的なドキュメンテーションツールとなります。
技術的詳細
このコミットは、log
パッケージのExampleLogger
関数をsrc/pkg/log/example_test.go
という新しいファイルに追加します。このファイルは、Goのテスト規約に従い、log_test
パッケージに属しています。これは、テスト対象のパッケージ(log
)とは異なるパッケージにテストを配置することで、外部からパッケージを使用する際の挙動をテストする「外部テスト」の形式を取っていることを意味します。
ExampleLogger
関数は、以下のステップでlog.Logger
の基本的な使用方法を示しています。
bytes.Buffer
の初期化:var buf bytes.Buffer
によって、ログメッセージを書き込むためのメモリ上のバッファが作成されます。これにより、ログ出力を標準出力に直接書き出すことなく、プログラム内でその内容をキャプチャし、検証することが可能になります。log.New
によるロガーの作成:logger := log.New(&buf, "logger: ", log.Lshortfile)
という行で、新しいlog.Logger
インスタンスが作成されます。- 第一引数
&buf
は、ログの出力先として先ほど作成したbytes.Buffer
のアドレスを渡しています。 - 第二引数
"logger: "
は、各ログメッセージの前に付加されるプレフィックスです。 - 第三引数
log.Lshortfile
は、ログメッセージにログを呼び出したソースファイル名と行番号を含めるためのフラグです。
- 第一引数
- ログメッセージの出力:
logger.Print("Hello, log file!")
によって、作成したロガーインスタンスを使用してログメッセージが出力されます。このメッセージはbuf
に書き込まれます。 - バッファの内容の出力:
fmt.Print(&buf)
によって、buf
に蓄積されたログメッセージが標準出力に書き出されます。これは、Example
テストの// Output:
コメントと比較するために必要です。 - 期待される出力の定義:
// Output:
コメントブロックは、このExample
関数が実行されたときに期待される正確な出力を定義しています。logger: example_test.go:15: Hello, log file!
- この出力は、設定されたプレフィックス(
logger:
)、ファイル名と行番号(example_test.go:15:
)、そして実際のログメッセージ(Hello, log file!
)が結合されたものです。行番号15
は、logger.Print
が呼び出されたexample_test.go
内の行番号に対応します。
このExample
関数は、go test
実行時に自動的にテストされ、その出力が// Output:
コメントと一致することが検証されます。これにより、log.New
の基本的な挙動と、log.Lshortfile
フラグの効果が明確に示され、ドキュメントとしても機能します。
コアとなるコードの変更箇所
src/pkg/log/example_test.go
という新しいファイルが追加され、以下の内容が記述されています。
--- /dev/null
+++ b/src/pkg/log/example_test.go
@@ -0,0 +1,21 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package log_test
+
+import (
+ "bytes"
+ "fmt"
+ "log"
+)
+
+func ExampleLogger() {
+ var buf bytes.Buffer
+ logger := log.New(&buf, "logger: ", log.Lshortfile)
+ logger.Print("Hello, log file!")
+
+ fmt.Print(&buf)
+ // Output:
+ // logger: example_test.go:15: Hello, log file!
+}
コアとなるコードの解説
追加されたExampleLogger
関数は、log
パッケージのカスタムロガーの作成と使用方法を簡潔に示しています。
package log_test
: この行は、このファイルがlog
パッケージの外部テストであることを示します。これにより、log
パッケージの公開されたAPIのみがテストされ、パッケージの内部実装に依存しないテストが保証されます。import
ブロック:"bytes"
:bytes.Buffer
を使用するためにインポートされます。"fmt"
:fmt.Print
を使用してバッファの内容を標準出力に書き出すためにインポートされます。"log"
: テスト対象のlog
パッケージ自体をインポートします。
func ExampleLogger()
: この関数は、Goのテストフレームワークによって特別なExample
テストとして認識されます。var buf bytes.Buffer
: ログメッセージをキャプチャするためのbytes.Buffer
インスタンスを宣言します。logger := log.New(&buf, "logger: ", log.Lshortfile)
:log.New
を呼び出して新しいロガーを作成します。&buf
: ログの出力先としてbuf
のアドレスを渡します。これにより、logger.Print
が呼び出されたときに、メッセージはbuf
に書き込まれます。"logger: "
: ログメッセージのプレフィックスを設定します。log.Lshortfile
: ログメッセージに、ログ呼び出し元のファイル名と行番号(例:example_test.go:15:
)を含めるように設定します。
logger.Print("Hello, log file!")
: 作成したロガーを使用して、指定された文字列をログに出力します。この出力はbuf
に格納されます。fmt.Print(&buf)
:buf
に蓄積されたすべての内容を標準出力に書き出します。これは、Example
テストの// Output:
コメントとの比較のために必要です。// Output:
コメント: この特別なコメントは、ExampleLogger
関数が実行されたときに期待される正確な出力を定義します。go test
コマンドは、実際の出力とこのコメントの内容を比較し、一致しない場合はテストを失敗させます。これにより、コード例が常に正しく、ドキュメントとして機能することが保証されます。
このコードは、log.New
の柔軟性、特にカスタム出力先とフラグの設定能力を明確に示しており、log
パッケージのドキュメントを補完する重要な役割を果たします。
関連リンク
- Go Issue 6028: log: add example
- Go Code Review CL 43320043: log: add example
参考にした情報源リンク
- Go言語
log
パッケージ公式ドキュメント: https://pkg.go.dev/log - Go言語
bytes
パッケージ公式ドキュメント: https://pkg.go.dev/bytes - Go言語
io
パッケージ公式ドキュメント: https://pkg.go.dev/io - Go言語のテストに関する公式ドキュメント(
Example
関数について): https://go.dev/blog/examples - Go言語のテストの書き方: https://go.dev/doc/tutorial/add-a-test
- Go言語の
go test
コマンド: https://go.dev/cmd/go/#hdr-Test_packages - Go言語の
go doc
コマンド: https://go.dev/cmd/go/#hdr-Show_documentation_for_package_or_symbol - Go言語の
log
パッケージのフラグに関する情報: https://pkg.go.dev/log#pkg-constants - Go言語の
io.Writer
インターフェースに関する情報: https://pkg.go.dev/io#Writer - Go言語の
bytes.Buffer
に関する情報: https://pkg.go.dev/bytes#Buffer - Go言語の
fmt
パッケージに関する情報: https://pkg.go.dev/fmt - Go言語の
package_test
とpackage
の違い: https://go.dev/doc/code#TestPackages - Go言語の
go test
における// Output:
の利用: https://go.dev/blog/examples