Zenn
Closed8

govipsのlog levelを設定する

ninomaeninomae

特に何もせずに実行すると以下のように大量のログがstderrに放出される。
開発環境やデバッグ中は助かるが、production環境でこれらが放出されるのは困りそう。なので、LogLevelを設定する方法を調べていく。

container1-1  | 2025/03/16 22:58:31 [VIPS.info] g_getenv( "PATH" ) == "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
container1-1  | 2025/03/16 22:58:31 [VIPS.info] looking in "/usr/local/sbin" for "govips"
container1-1  | 2025/03/16 22:58:31 [VIPS.info] looking in "/usr/local/bin" for "govips"
container1-1  | 2025/03/16 22:58:31 [VIPS.info] looking in "/usr/sbin" for "govips"
container1-1  | 2025/03/16 22:58:31 [VIPS.info] looking in "/usr/bin" for "govips"
container1-1  | 2025/03/16 22:58:31 [VIPS.info] looking in "/sbin" for "govips"
container1-1  | 2025/03/16 22:58:31 [VIPS.info] looking in "/bin" for "govips"
container1-1  | 2025/03/16 22:58:31 [VIPS.info] trying for dir = "//govips", name = "govips"
container1-1  | 2025/03/16 22:58:31 [VIPS.info] canonicalised path = ""
container1-1  | 2025/03/16 22:58:31 [VIPS.info] VIPS_PREFIX = /usr
container1-1  | 2025/03/16 22:58:31 [VIPS.info] VIPS_LIBDIR = /usr/lib/aarch64-linux-gnu
container1-1  | 2025/03/16 22:58:31 [VIPS.info] prefix = /usr
container1-1  | 2025/03/16 22:58:31 [VIPS.info] libdir = /usr/lib/aarch64-linux-gnu
container1-1  | 2025/03/16 22:58:31 [VIPS.info] searching "/usr/lib/aarch64-linux-gnu/vips-modules-8.14"
container1-1  | 2025/03/16 22:58:31 [VIPS.info] searching "/usr/lib/aarch64-linux-gnu/vips-plugins-8.14"
container1-1  | 2025/03/16 22:58:31 [govips.info] vips 8.14.1 started with concurrency=1 cache_max_files=0 cache_max_mem=52428800 cache_max=100
container1-1  | 2025/03/16 22:58:31 [govips.info] registered image type loader type=jp2k
container1-1  | 2025/03/16 22:58:31 [govips.info] registered image type loader type=png
container1-1  | 2025/03/16 22:58:31 [govips.info] registered image type loader type=tiff
container1-1  | 2025/03/16 22:58:31 [govips.info] registered image type loader type=gif
container1-1  | 2025/03/16 22:58:31 [govips.info] registered image type loader type=jpeg
container1-1  | 2025/03/16 22:58:31 [govips.info] registered image type loader type=svg
container1-1  | 2025/03/16 22:58:31 [govips.info] registered image type loader type=webp
container1-1  | 2025/03/16 22:58:31 [VIPS.info] selected loader is image source
container1-1  | 2025/03/16 22:58:31 [VIPS.info] input size is 960 x 540
container1-1  | 2025/03/16 22:58:31 [VIPS.info] loading with factor 1 pre-shrink
container1-1  | 2025/03/16 22:58:31 [VIPS.info] pre-shrunk size is 960 x 540
container1-1  | 2025/03/16 22:58:31 [VIPS.info] converting to processing space srgb
container1-1  | 2025/03/16 22:58:31 [VIPS.info] residual reducev by 0.37037
container1-1  | 2025/03/16 22:58:31 [VIPS.info] reducev: 17 point mask
container1-1  | 2025/03/16 22:58:31 [VIPS.info] reducev: using vector path
container1-1  | 2025/03/16 22:58:31 [VIPS.info] residual reduceh by 0.37037
container1-1  | 2025/03/16 22:58:31 [VIPS.info] reduceh: 17 point mask
container1-1  | 2025/03/16 22:58:31 [VIPS.info] converting to output space srgb
container1-1  | 2025/03/16 22:58:31 [VIPS.info] cropping to 200x200
ninomaeninomae

https://pkg.go.dev/github.com/davidbyttow/govips/v2@v2.16.0/vips#LoggingSettings
Logハンドラーのセッターはあるっぽいのでこれを深堀りする。

https://pkg.go.dev/github.com/davidbyttow/govips/v2@v2.16.0/vips#LoggingHandlerFunction

LoggingHandlerFunction is a function which will be called for each log message. By default, govips sends logging messages to os.Stderr. If you want to log elsewhere such as to a file or to a state variable which you inspect yourself, define a new logging handler function and set it via LoggingSettings().

  • デフォルトではstderrにログを出力する
  • ファイルなど他のところに出力してほしいときは、LoggingHandlerFuntion型の関数を定義して、LoggingSetting関数から設定してね

とのこと

ninomaeninomae

https://pkg.go.dev/github.com/davidbyttow/govips/v2@v2.16.0/vips#LogLevel

const (
	LogLevelError    LogLevel = C.G_LOG_LEVEL_ERROR
	LogLevelCritical LogLevel = C.G_LOG_LEVEL_CRITICAL
	LogLevelWarning  LogLevel = C.G_LOG_LEVEL_WARNING
	LogLevelMessage  LogLevel = C.G_LOG_LEVEL_MESSAGE
	LogLevelInfo     LogLevel = C.G_LOG_LEVEL_INFO
	LogLevelDebug    LogLevel = C.G_LOG_LEVEL_DEBUG
)
  • LogLevelは5種類ある模様。
  • production環境ではError, Critical, Warningあたりを出力して、あとのログは捨てても良いかもしれない(ご自分の要件に応じて適切に設定してくださいね)
ninomaeninomae

https://github.com/davidbyttow/govips/blob/8d9c5493bcbc5b0cceb6467fb3fdc53c9fe984d4/vips/logging.go#L72-L90

govipsがデフォルトで設定してくれるロギングハンドラの実装。stdlibのlogパッケージを使ってシンプルに実装している。(logパッケージを使っているからstderrに出力するのね。納得)

このデフォルトのロギングハンドラはprivate関数になっているので、直接プロジェクトファイルで使うことはできない。というわけで、独自のロギングハンドラを実装していく

ninomaeninomae

最終的にはこのような形でサンプルを作ってみた
すべてのログレベルに対して、定義したハンドラをセットするイメージ。loglevel別にハンドラを作りたいなら、それぞれ作ればカスタマイズできそう
APP_ENVがproduction以外のときには、デフォルトのハンドラをそのまま使う構成にしている

package main

import (
	"fmt"
	"log"
	"os"

	"github.com/caarlos0/env/v11"
	"github.com/davidbyttow/govips/v2/vips"
)

type Config struct {
	AppEnv string `env:"APP_ENV"`
}

var cfg Config

func init() {
	err := env.Parse(&cfg)
	if err != nil {
		log.Fatalf("%+v\n", err)
	}
}

func loggingHandler(messageDomain string, messageLevel vips.LogLevel, message string) {
	var messageLevelDescription string
	switch messageLevel {
	case vips.LogLevelError:
		messageLevelDescription = "error"
	case vips.LogLevelCritical:
		messageLevelDescription = "critical"
	case vips.LogLevelWarning:
		messageLevelDescription = "warning"
	default:
		return
	}
	log.Printf("[%v.%v] %v", messageDomain, messageLevelDescription, message)
}

func main() {
	vips.Startup(nil)
	defer vips.Shutdown()
	// NOTE: In production, only log errors and critical, warning messages
	if cfg.AppEnv == "production" {
		vips.LoggingSettings(loggingHandler, vips.LogLevelError)
		vips.LoggingSettings(loggingHandler, vips.LogLevelCritical)
		vips.LoggingSettings(loggingHandler, vips.LogLevelWarning)
		vips.LoggingSettings(loggingHandler, vips.LogLevelMessage)
		vips.LoggingSettings(loggingHandler, vips.LogLevelInfo)
		vips.LoggingSettings(loggingHandler, vips.LogLevelDebug)
	}

	image1, err := vips.NewImageFromFile("./input.png")
	if err != nil {
		log.Fatalf("error loading image: %v", err)
	}

	err = image1.Thumbnail(200, 200, vips.InterestingCentre)
	if err != nil {
		log.Fatalf("error resizing image: %v", err)
	}

	ep := vips.NewPngExportParams()
	b, _, err := image1.ExportPng(ep)
	if err != nil {
		log.Fatalf("error exporting image: %v", err)
	}
	err = os.WriteFile("./output.png", b, 0644)
	if err != nil {
		log.Fatalf("error writing image: %v", err)
	}
}

ninomaeninomae

サンプルの実行結果はこのような感じ.
registered image type loader ...以下のログがAPP_ENV="production"のときは出力されないようになっている

container1-1  | 2025/03/16 23:15:29 [VIPS.info] g_getenv( "PATH" ) == "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
container1-1  | 2025/03/16 23:15:29 [VIPS.info] looking in "/usr/local/sbin" for "govips"
container1-1  | 2025/03/16 23:15:29 [VIPS.info] looking in "/usr/local/bin" for "govips"
container1-1  | 2025/03/16 23:15:29 [VIPS.info] looking in "/usr/sbin" for "govips"
container1-1  | 2025/03/16 23:15:29 [VIPS.info] looking in "/usr/bin" for "govips"
container1-1  | 2025/03/16 23:15:29 [VIPS.info] looking in "/sbin" for "govips"
container1-1  | 2025/03/16 23:15:29 [VIPS.info] looking in "/bin" for "govips"
container1-1  | 2025/03/16 23:15:29 [VIPS.info] trying for dir = "//govips", name = "govips"
container1-1  | 2025/03/16 23:15:29 [VIPS.info] canonicalised path = ""
container1-1  | 2025/03/16 23:15:29 [VIPS.info] VIPS_PREFIX = /usr
container1-1  | 2025/03/16 23:15:29 [VIPS.info] VIPS_LIBDIR = /usr/lib/aarch64-linux-gnu
container1-1  | 2025/03/16 23:15:29 [VIPS.info] prefix = /usr
container1-1  | 2025/03/16 23:15:29 [VIPS.info] libdir = /usr/lib/aarch64-linux-gnu
container1-1  | 2025/03/16 23:15:29 [VIPS.info] searching "/usr/lib/aarch64-linux-gnu/vips-modules-8.14"
container1-1  | 2025/03/16 23:15:29 [VIPS.info] searching "/usr/lib/aarch64-linux-gnu/vips-plugins-8.14"
container1-1  | 2025/03/16 23:15:29 [govips.info] vips 8.14.1 started with concurrency=1 cache_max_files=0 cache_max_mem=52428800 cache_max=100
container1-1  | 2025/03/16 23:15:29 [govips.info] registered image type loader type=svg
container1-1  | 2025/03/16 23:15:29 [govips.info] registered image type loader type=jp2k
container1-1  | 2025/03/16 23:15:29 [govips.info] registered image type loader type=png
container1-1  | 2025/03/16 23:15:29 [govips.info] registered image type loader type=tiff
container1-1  | 2025/03/16 23:15:29 [govips.info] registered image type loader type=webp
container1-1  | 2025/03/16 23:15:29 [govips.info] registered image type loader type=gif
container1-1  | 2025/03/16 23:15:29 [govips.info] registered image type loader type=jpeg

ちなみに、registered image typeまでのログはvips.Startupで起動する際に設定されているので、ユーザー側では抑制できないかもしれない。あっても困らないし、出力してくれていいと思うのでこれにて終了

ninomaeninomae

govipsはCGoを使って作られているパッケージなので、マルチステージビルドでproduction用のイメージを作っているときは少しだけ注意が必要だった
これについては近いうちに記事にしようと思う。

このスクラップは16日前にクローズされました
作成者以外のコメントは許可されていません