Полное описание пакета log в Go
Полное описание пакета log в Go с примерами применения и разными потоками вывода
Categories:
Пакет log
в Go предоставляет простые и эффективные инструменты для логирования. Он поддерживает:
- Вывод логов в стандартный вывод (
stdout
/stderr
). - Настройку формата вывода (префиксы, дата/время, уровень логирования).
- Запись логов в файлы.
- Гибкую настройку через
log.Logger
.
1. Основные функции пакета log
1.1. Простое логирование
Пакет log
предоставляет стандартные функции:
log.Print("Обычное сообщение") // Вывод без формата
log.Printf("Формат: %d", 123) // Форматированный вывод
log.Println("Сообщение с новой строкой") // Вывод с \n
1.2. Логирование с уровнем FATAL (завершение программы)
log.Fatal("Сообщение и выход с os.Exit(1)") // Вывод + exit(1)
log.Fatalf("Формат: %s", "ошибка") // Форматированный вывод + exit(1)
log.Fatalln("Фатальная ошибка") // Вывод + exit(1)
1.3. Логирование с уровнем PANIC (вызов паники)
log.Panic("Паника с выводом стека") // Вывод + panic()
log.Panicf("Ошибка: %v", err) // Форматированный вывод + panic()
log.Panicln("Критическая ошибка") // Вывод + panic()
2. Настройка формата вывода
2.1. Добавление префикса (дата, время, уровень)
log.SetPrefix("ERROR: ") // Установка префикса
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) // Формат
log.Println("Сообщение с префиксом")
Вывод:
ERROR: 2024/03/15 14:20:10 main.go:10: Сообщение с префиксом
2.2. Доступные флаги для log.SetFlags
Флаг | Описание |
---|---|
log.Ldate |
Дата (2006/01/02 ) |
log.Ltime |
Время (15:04:05 ) |
log.Lmicroseconds |
Микросекунды (15:04:05.000000 ) |
log.Llongfile |
Полный путь к файлу (/a/b/c.go:10 ) |
log.Lshortfile |
Короткое имя файла (c.go:10 ) |
log.LUTC |
Вывод времени в UTC |
log.Lmsgprefix |
Префикс перед сообщением (Go 1.14+) |
Пример комбинации флагов:
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile | log.Lmsgprefix)
3. Запись логов в файл
file, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
log.Fatal("Ошибка открытия файла:", err)
}
defer file.Close()
log.SetOutput(file) // Перенаправляем вывод в файл
log.Println("Сообщение записано в app.log")
4. Создание нескольких логгеров
Можно создавать отдельные логгеры для разных целей:
logger := log.New(os.Stdout, "INFO: ", log.Ldate|log.Ltime)
errorLogger := log.New(os.Stderr, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile)
logger.Println("Информационное сообщение")
errorLogger.Println("Ошибка в программе")
Вывод:
INFO: 2024/03/15 14:20:10 Информационное сообщение
ERROR: 2024/03/15 14:20:10 main.go:15: Ошибка в программе
5. Продвинутое использование (JSON-логирование, уровни)
Стандартный log
не поддерживает уровни (DEBUG
, INFO
, WARN
, ERROR
), но их можно эмулировать:
5.1. Логирование в JSON
type LogEntry struct {
Level string `json:"level"`
Message string `json:"message"`
Time string `json:"time"`
}
func JSONLog(level, message string) {
entry := LogEntry{
Level: level,
Message: message,
Time: time.Now().Format(time.RFC3339),
}
data, _ := json.Marshal(entry)
log.Println(string(data))
}
JSONLog("INFO", "Запуск сервера")
Вывод:
{"level":"INFO","message":"Запуск сервера","time":"2024-03-15T14:20:10Z"}
5.2. Уровни логирования
const (
LevelDebug = "DEBUG"
LevelInfo = "INFO"
LevelWarn = "WARN"
LevelError = "ERROR"
)
func Log(level, message string) {
log.Printf("[%s] %s", level, message)
}
Log(LevelError, "Сервер не отвечает")
Вывод:
$$[ERROR] Сервер не отвечает$$
6. Когда использовать log
, а когда другие пакеты?
log
— для простых задач (CLI-утилиты, маленькие сервисы).slog
(Go 1.21+) — структурированное логирование с уровнями.zap
/zerolog
— для высоконагруженных приложений (минимальные аллокации).
Вывод
- Пакет
log
прост, но гибок (префиксы, файлы, форматирование). - Подходит для базового логирования.
- Для сложных сценариев лучше использовать
slog
,zap
илиzerolog
. - Можно комбинировать с
io.MultiWriter
для вывода в несколько мест.
Пример MultiWriter:
file, _ := os.OpenFile("app.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
multiWriter := io.MultiWriter(os.Stdout, file)
log.SetOutput(multiWriter)
log.Println("Сообщение в консоль и файл")