Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41bdd6685a | ||
|
|
14778f40f6 | ||
|
|
9baa9ec5a2 | ||
|
|
11e3eb1de0 | ||
|
|
1a3c40140a | ||
|
|
a49abdd715 | ||
|
|
e000489790 | ||
|
|
02fd7bd448 | ||
|
|
682553931f | ||
|
|
8ee469a10e | ||
|
|
2e857bc724 | ||
|
|
fcd8ec8b5b | ||
|
|
1606e89a4a | ||
|
|
9943dbad17 | ||
|
|
b8ffe727ee | ||
|
|
c572f16ac0 | ||
|
|
5f78f7da2c | ||
|
|
9ec26ec735 | ||
|
|
a5e8896870 | ||
|
|
06a5cb69cf | ||
|
|
6523ec8840 | ||
|
|
48050fe3cc | ||
|
|
289d6e27c9 | ||
|
|
4c0aaee87d | ||
|
|
5529026bc1 | ||
|
|
b7b6ff02b9 | ||
|
|
3f46be0e7e | ||
|
|
7ccffb7095 | ||
|
|
9fb19c8c32 | ||
|
|
05f12e2d50 | ||
|
|
d22c83bc4e | ||
|
|
545b85908c | ||
|
|
f94136938f | ||
|
|
eb71029cd5 | ||
|
|
6d509c8018 | ||
|
|
6fe13e8605 | ||
|
|
c4fa8c07df |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,5 +1,5 @@
|
|||||||
.idea/**
|
.idea/**
|
||||||
.vscode/**
|
.vscode/**
|
||||||
.vstags
|
.vstags
|
||||||
data/config.json
|
/data/config.json
|
||||||
aleesa-misc-go
|
/aleesa-misc-go
|
||||||
|
|||||||
67
.golangci.yml
Normal file
67
.golangci.yml
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
run:
|
||||||
|
tests: false
|
||||||
|
modules-download-mode: readonly
|
||||||
|
allow-parallel-runners: true
|
||||||
|
go: '1.24'
|
||||||
|
output:
|
||||||
|
sort-results: true
|
||||||
|
linters-settings:
|
||||||
|
gosec:
|
||||||
|
excludes:
|
||||||
|
# Оно не используется для повышения безопасности или каких-то таких секъюрных вещей, оно используется для выборки
|
||||||
|
# произвольного элемента из массива, так что ИДИ НАХУЙ с этой проверкой и не еби мозги липовой безопасностью.
|
||||||
|
- G404 # Insecure random number source (rand)
|
||||||
|
issues:
|
||||||
|
exclude-dirs:
|
||||||
|
- data
|
||||||
|
- vendor
|
||||||
|
linters:
|
||||||
|
disable-all: true
|
||||||
|
enable:
|
||||||
|
- copyloopvar
|
||||||
|
- errcheck
|
||||||
|
- gosimple
|
||||||
|
- govet
|
||||||
|
- ineffassign
|
||||||
|
- staticcheck
|
||||||
|
- unused
|
||||||
|
- asasalint
|
||||||
|
- asciicheck
|
||||||
|
- bodyclose
|
||||||
|
- containedctx
|
||||||
|
- contextcheck
|
||||||
|
- decorder
|
||||||
|
- durationcheck
|
||||||
|
- errchkjson
|
||||||
|
- errorlint
|
||||||
|
- exhaustive
|
||||||
|
- ginkgolinter
|
||||||
|
- gocheckcompilerdirectives
|
||||||
|
- gocritic
|
||||||
|
- godot
|
||||||
|
- gofmt
|
||||||
|
- goimports
|
||||||
|
- gosec
|
||||||
|
- gosmopolitan
|
||||||
|
- grouper
|
||||||
|
- importas
|
||||||
|
- ireturn
|
||||||
|
- makezero
|
||||||
|
- mirror
|
||||||
|
- nakedret
|
||||||
|
- nilerr
|
||||||
|
- nilnil
|
||||||
|
- nlreturn
|
||||||
|
- noctx
|
||||||
|
- nolintlint
|
||||||
|
- nonamedreturns
|
||||||
|
- predeclared
|
||||||
|
- promlinter
|
||||||
|
- reassign
|
||||||
|
- revive
|
||||||
|
- rowserrcheck
|
||||||
|
- stylecheck
|
||||||
|
- unconvert
|
||||||
|
- wastedassign
|
||||||
|
- whitespace
|
||||||
|
- wsl
|
||||||
73
Makefile
73
Makefile
@@ -1,22 +1,77 @@
|
|||||||
#!/usr/bin/env gmake -f
|
#!/usr/bin/env gmake -f
|
||||||
|
|
||||||
GOOPTS=CGO_ENABLED=0
|
GOOPTS=CGO_ENABLED=0
|
||||||
BUILDOPTS=-ldflags="-s -w" -a -gcflags=all=-l
|
BUILDOPTS=-ldflags="-s -w" -a -gcflags=all=-l -trimpath -buildvcs=false
|
||||||
|
MYNAME=aleesa-misc-go
|
||||||
|
BINARY=${MYNAME}
|
||||||
|
UNIX_BINARY=${MYNAME}
|
||||||
|
WINDOWS_BINARY=${MYNAME}.exe
|
||||||
|
RMCMD=rm -rf
|
||||||
|
|
||||||
|
# На windows имя бинарника может зависеть не только от платформы, но и от выбранной цели, для linux-а суффикс .exe
|
||||||
|
# не нужен
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
ifdef GOOS
|
||||||
|
ifeq ($(GOOS),windows)
|
||||||
|
BINARY=${WINDOWS_BINARY}
|
||||||
|
else # not ifeq ($(GOOS),windows)
|
||||||
|
BINARY=${MYNAME}
|
||||||
|
endif # ifeq ($(GOOS),windows)
|
||||||
|
else # not ifdef GOOS
|
||||||
|
BINARY=${WINDOWS_BINARY}
|
||||||
|
endif # ifdef GOOS
|
||||||
|
ifeq ($(SHELL), sh.exe)
|
||||||
|
RMCMD=DEL /Q /F
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Явно определяем символ новой строки, чтобы избежать неоднозначности на windows
|
||||||
|
define IFS
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
|
||||||
all: clean build
|
all: clean build
|
||||||
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
${GOOPTS} go build ${BUILDOPTS}
|
ifeq ($(OS),Windows_NT)
|
||||||
|
# Looks like on windows gnu make explicitly set SHELL to sh.exe, if it was not set.
|
||||||
|
ifeq ($(SHELL), sh.exe)
|
||||||
|
# # Vanilla cmd.exe / powershell.
|
||||||
|
SET "CGO_ENABLED=0"
|
||||||
|
go build ${BUILDOPTS} -o ${BINARY} ./cmd/${MYNAME}
|
||||||
|
else ifeq (,$(findstring(Git/usr/bin/sh.exe, $(SHELL))))
|
||||||
|
# # git-bash
|
||||||
|
CGO_ENABLED=0 go build ${BUILDOPTS} -o ${BINARY} ./cmd/${MYNAME}
|
||||||
|
else # not ifeq (,$(findstring(Git/usr/bin/sh.exe, $(SHELL))))
|
||||||
|
# # Some other shell.
|
||||||
|
# # TODO: handle it.
|
||||||
|
$(info "-- Dunno how to handle this shell: ${SHELL}")
|
||||||
|
endif # ifeq (,$(findstring(Git/usr/bin/sh.exe, $(SHELL))))
|
||||||
|
else # not ($(OS),Windows_NT)
|
||||||
|
CGO_ENABLED=0 go build ${BUILDOPTS} -o ${BINARY} ./cmd/${MYNAME}
|
||||||
|
endif # ifeq ($(OS),Windows_NT)
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
go clean
|
ifeq ($(OS),Windows_NT)
|
||||||
|
ifeq ($(SHELL),sh.exe)
|
||||||
|
# # Vanilla cmd.exe / powershell.
|
||||||
|
if exist ${WINDOWS_BINARY} ${RMCMD} ${WINDOWS_BINARY}
|
||||||
|
if exist ${UNIX_BINARY} ${RMCMD} ${UNIX_BINARY}
|
||||||
|
else # not ifeq ($(SHELL),sh.exe)
|
||||||
|
${RMCMD} ./${WINDOWS_BINARY}
|
||||||
|
${RMCMD} ./${UNIX_BINARY}
|
||||||
|
endif # ifeq ($(SHELL),sh.exe)
|
||||||
|
else # not ifeq ($(OS),Windows_NT)
|
||||||
|
${RMCMD} ./${BINARY}
|
||||||
|
endif
|
||||||
|
|
||||||
wipe:
|
|
||||||
go clean
|
|
||||||
rm -rf go.{mod,sum}
|
|
||||||
|
|
||||||
prep:
|
upgrade:
|
||||||
go mod init main
|
go get -u ./...
|
||||||
go mod tidy -compat=1.18
|
go mod tidy
|
||||||
|
go mod vendor
|
||||||
|
|
||||||
# vim: set ft=make noet ai ts=4 sw=4 sts=4:
|
# vim: set ft=make noet ai ts=4 sw=4 sts=4:
|
||||||
|
|||||||
111
README
111
README
@@ -1,111 +0,0 @@
|
|||||||
aleesa-misc-go
|
|
||||||
-----------------------------------------------------------------------------------------------------------------------
|
|
||||||
Основной роутер команд для aleesa-bot. Все протокольные плагины шлют команды сюда, а отсюда команды разлетаются в
|
|
||||||
модули-исполнители и ответ от исполнителей идёт обратно заказчику.
|
|
||||||
Работает по протоколу Redis pubsub.
|
|
||||||
|
|
||||||
|
|
||||||
Механика работы
|
|
||||||
-----------------------------------------------------------------------------------------------------------------------
|
|
||||||
Роутер подписан на канал misc (тот, который указан в поле channel конфига).
|
|
||||||
|
|
||||||
Модули, реализующие "клиентские протоколы" - telegram, irc, jabber и проч, подписаны на канал своего протокола.
|
|
||||||
Входящие сообщения они получают только через этот канал.
|
|
||||||
|
|
||||||
Модули, реализующие иную функциональность также подписаны каждый на свой канал. Кроме того, для реализации
|
|
||||||
дополнительных синхронных возможностей, они могут слушать например http запросы на отдельных - ip:портах. Но это уже
|
|
||||||
модуль-специфичная настройка.
|
|
||||||
|
|
||||||
Формат протокола - это json с полями:
|
|
||||||
from - модуль (по сути, redis-канал), в который надо ответить
|
|
||||||
chatid - чат, из которого прилетело сообщение
|
|
||||||
userid - пользователь, на чью фразу мы отвечаем, или пользователь, для которого предназначается ответ
|
|
||||||
message - текст сообщения
|
|
||||||
plugin - первоначальный источник (по сути, redis-канал) сообщения.
|
|
||||||
mode - public или private
|
|
||||||
|
|
||||||
misc - объект с дополнительными полями:
|
|
||||||
|
|
||||||
misc->answer - 0 если ответ не требуется и 1 если ответ требуется (использован в модуле craniac), значение
|
|
||||||
по-умолчанию 1, если поля нет.
|
|
||||||
|
|
||||||
misc->bot_nick - ник бота. Типа как, для разных чятов он может быть разный. (Использовано в модуле craniac.) Если
|
|
||||||
поле отсутствует, проверка на обращение к боту по нику не происходит.
|
|
||||||
|
|
||||||
misc->csign - command sign - значок, которым предваряется команда в чятике. Исторически сложилось так, что для
|
|
||||||
разных ботов этот символ был разный, например, eggdrop использовал точку, а sulci - восклицательный
|
|
||||||
знак. По-умолчанию, aleesa-bot вездепроставляет восклицательный знак, если во входящем сообщении
|
|
||||||
такой настройки нету. Изначально настройка задаётся в конфиге чат-модуля (aleesa-telegram,
|
|
||||||
например).
|
|
||||||
|
|
||||||
misc->fwd_cnt - количество пересылок сообщения. Значение по-умолчанию 1. Предполагается, что при пересылке
|
|
||||||
сообщения, модуль будет инкрементировать это значение и заодно проверять, что оно не превышает
|
|
||||||
настройку forwards_max в конфиге или 5, если в конфиге такой настройки нету.
|
|
||||||
|
|
||||||
misc->good_morning - флажок признака сообщения-фразы дня, которая по идее осылается в ~8 часов по мск. Используется в
|
|
||||||
модуле phrases.
|
|
||||||
|
|
||||||
misc->msg_format - Использовать форматирование в сообщении. На текущий момент этот флажок выставляется в модуле
|
|
||||||
telegram и благополучно проходит через модуль misc, далее попадает в модуль phrases, и, наконец,
|
|
||||||
возвращается в модуль telegram, чтобы выходное сообщение было отослано как отформатированное.
|
|
||||||
|
|
||||||
misc->username - имя пользователя, по которому к нему надо обратиться в ответе (используется в модуле games). Для
|
|
||||||
telegram это фактически ссылка на пользователя, как правило с его firstname и lastname (или
|
|
||||||
@username, если firstname и lastname у него нету), чтобы его можно было захайлатить.
|
|
||||||
|
|
||||||
|
|
||||||
Как это собрать?
|
|
||||||
-----------------------------------------------------------------------------------------------------------------------
|
|
||||||
Понадобится golang версии 1.18 или более новая.
|
|
||||||
|
|
||||||
Сам процесс сборки простой, достаточно запустить:
|
|
||||||
make
|
|
||||||
|
|
||||||
и через некоторое время мы получаем бинарник aleesa-misc-go. Это и есть наше приложение.
|
|
||||||
|
|
||||||
|
|
||||||
Как это запустить?
|
|
||||||
-----------------------------------------------------------------------------------------------------------------------
|
|
||||||
Приложение тестировалось на alpine linux x86_64 3.16, но должно работать на любом (более свежем) linux-е.
|
|
||||||
|
|
||||||
После создания data/config.json из data/config_sample.json, можно запускать приложение.
|
|
||||||
|
|
||||||
Предполагается, что конфиг написан в формате human json (https://hjson.github.io), который допускает коментарии и
|
|
||||||
некоторые другие вольности в форматировании json-а. Конфиг ищется последовательно по следующим путям по принципу "кто
|
|
||||||
первый того и тапки":
|
|
||||||
~/.aleesa-misc-go.json
|
|
||||||
~/aleesa-misc-go.json
|
|
||||||
/etc/aleesa-misc-go.json
|
|
||||||
data/config.json
|
|
||||||
|
|
||||||
В каталоге contrib находится скрипт для alpine linux, системы инициализации openrc. Этот скрипт достаточно положить в
|
|
||||||
/etc/init.d/aleesa-misc-go. После чего скопировать бинарник в каталог /var/lib/aleesa-misc-go, положить конфиг в одну
|
|
||||||
из дефолтных локаций (тестировалась /var/lib/aleesa-misc-go/data/config.json) и после этого сервис запускается
|
|
||||||
командой:
|
|
||||||
service aleesa-misc-go start
|
|
||||||
|
|
||||||
В автозагрузку его можно прописать через команду:
|
|
||||||
rc-update add aleesa-misc-go default
|
|
||||||
|
|
||||||
|
|
||||||
Nota Bene
|
|
||||||
-----------------------------------------------------------------------------------------------------------------------
|
|
||||||
По механике, в процессе работы мы форкаем горутинки на каждое входящее сообщение, особо не контроллируя этот процесс.
|
|
||||||
Предполагается, что на этот роутер не будет большой нагрузки, даже если будет несколько ботов на входе - ограничения
|
|
||||||
телеграма и других мессенджеров не должны дать возможности развить достаточно большой message rate, чтобы об это
|
|
||||||
споткнуться.
|
|
||||||
|
|
||||||
Формально, более удачным было бы иметь автоматический пул воркеров-горутинок и раскидывать им через channel-ы
|
|
||||||
сообщения. Внутри каждой горутинки можно было бы повиcнуть в бесконечном цикле на канале входящих сообщений и так и
|
|
||||||
работать. Но на практике оно того не стОит.
|
|
||||||
|
|
||||||
|
|
||||||
Nota Bene #2
|
|
||||||
-----------------------------------------------------------------------------------------------------------------------
|
|
||||||
Go не поддерживает системный вызов fork() из-за чего демонизация программ на гошке средствами самой гошки - это в
|
|
||||||
некотором роде проблема. Решается она с помощью утилиты daemonize (https://github.com/bmc/daemonize).
|
|
||||||
|
|
||||||
Соответствено, если для запуска этой программы предполагается использовать возможности демонизации, то можно
|
|
||||||
воспользоваться этой программой.
|
|
||||||
|
|
||||||
В alpine linux есть средства openrc для супервайзинга foreground-сервисов.
|
|
||||||
73
README.md
Normal file
73
README.md
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
# aleesa-misc-go
|
||||||
|
|
||||||
|
Основной роутер команд для aleesa-bot. Все протокольные плагины шлют команды сюда, а отсюда команды разлетаются в
|
||||||
|
модули-исполнители и ответ от исполнителей идёт обратно заказчику.
|
||||||
|
|
||||||
|
Работает по протоколу Redis pubsub.
|
||||||
|
|
||||||
|
## Механика работы
|
||||||
|
|
||||||
|
Роутер подписан на канал misc (тот, который указан в поле channel конфига).
|
||||||
|
|
||||||
|
Модули, реализующие "клиентские протоколы" - telegram, irc, jabber и проч, подписаны на канал своего протокола.
|
||||||
|
Входящие сообщения они получают только через этот канал.
|
||||||
|
|
||||||
|
Модули, реализующие иную функциональность также подписаны каждый на свой канал. Роутер распознаёт команду и направляет
|
||||||
|
её в канал соответствующего бэкэнд-сервиса, который уже дальше работает в соответствии со своей бизнес-логикой.
|
||||||
|
|
||||||
|
## Как это собрать?
|
||||||
|
|
||||||
|
Понадобится компилятор go версии 1.25.1 или более новый.
|
||||||
|
|
||||||
|
Сам процесс сборки простой, достаточно запустить make или gmake, в зависимости от платформы:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
и через некоторое время мы получаем бинарник **aleesa-misc-go**. Это и есть наше приложение.
|
||||||
|
|
||||||
|
## Как это запустить?
|
||||||
|
|
||||||
|
Приложение тестировалось на Alpine linux x86_64 3.16, но должно работать на любом (более свежем) linux-е.
|
||||||
|
|
||||||
|
После создания **data/config.json** из **data/config_sample.json**, можно запускать приложение.
|
||||||
|
|
||||||
|
Предполагается, что конфиг написан в формате [human json](https://hjson.github.io), который допускает коментарии и
|
||||||
|
некоторые другие вольности в форматировании json-а. Конфиг ищется последовательно по следующим путям по принципу "кто
|
||||||
|
первый того и тапки":
|
||||||
|
|
||||||
|
```
|
||||||
|
~/.aleesa-misc-go.json
|
||||||
|
~/aleesa-misc-go.json
|
||||||
|
/etc/aleesa-misc-go.json
|
||||||
|
data/config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
В каталоге contrib находится скрипт для alpine linux, системы инициализации openrc. Этот скрипт достаточно положить в
|
||||||
|
**/etc/init.d/aleesa-misc-go**. После чего скопировать бинарник в каталог **/var/lib/aleesa-misc-go**, положить конфиг в
|
||||||
|
одну из дефолтных локаций (тестировалась **/var/lib/aleesa-misc-go/data/config.json**) и после этого сервис запускается
|
||||||
|
командой:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
service aleesa-misc-go start
|
||||||
|
```
|
||||||
|
|
||||||
|
В автозагрузку его можно прописать через команду:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rc-update add aleesa-misc-go default
|
||||||
|
```
|
||||||
|
|
||||||
|
## Nota Bene #1
|
||||||
|
|
||||||
|
Go не поддерживает системный вызов fork() из-за чего демонизация программ на гошке средствами самой гошки - это в
|
||||||
|
некотором роде проблема. Решается она с помощью утилиты [daemonize](https://github.com/bmc/daemonize).
|
||||||
|
|
||||||
|
Соответствено, если для запуска этой программы предполагается использовать возможности демонизации, то можно
|
||||||
|
воспользоваться этой программой.
|
||||||
|
|
||||||
|
В alpine linux есть средства openrc для супервайзинга foreground-сервисов.
|
||||||
|
|
||||||
|
Технически, можно было бы решить эту проблему fork()-а с помощью "github.com/sevlyar/go-daemon", но на текущий момент
|
||||||
|
она не стоит остро, поэтому решения не требуется.
|
||||||
7
TODO
Normal file
7
TODO
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Добавить в протокол секцию nsfw/censor.
|
||||||
|
|
||||||
|
В качестве валидатора использовать какую-нить готовую либу
|
||||||
|
https://gookit.github.io/validate/#/
|
||||||
|
github.com/go-playground/validator/v10
|
||||||
|
|
||||||
|
https://awesome-go.com/validation/
|
||||||
@@ -1,378 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/hjson/hjson-go"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Горутинка, которая парсит json-чики прилетевшие из REDIS-ки
|
|
||||||
func msgParser(ctx context.Context, msg string) {
|
|
||||||
var sendTo = "craniac"
|
|
||||||
var j rMsg
|
|
||||||
|
|
||||||
log.Debugf("Incomming raw json: %s", msg)
|
|
||||||
|
|
||||||
if err := json.Unmarshal([]byte(msg), &j); err != nil {
|
|
||||||
log.Warnf("Unable to to parse message from redis channel: %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate our j
|
|
||||||
if exist := j.From; exist == "" {
|
|
||||||
log.Warnf("Incorrect msg from redis, no from field: %s", msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if exist := j.Chatid; exist == "" {
|
|
||||||
log.Warnf("Incorrect msg from redis, no chatid field: %s", msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if exist := j.Userid; exist == "" {
|
|
||||||
log.Warnf("Incorrect msg from redis, no userid field: %s", msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if exist := j.Message; exist == "" {
|
|
||||||
log.Warnf("Incorrect msg from redis, no message field: %s", msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if exist := j.Plugin; exist == "" {
|
|
||||||
log.Warnf("Incorrect msg from redis, no plugin field: %s", msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if exist := j.Mode; exist == "" {
|
|
||||||
log.Warnf("Incorrect msg from redis, no mode field: %s", msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// j.Misc.Answer может и не быть, тогда ответа на такое сообщение не будет
|
|
||||||
// j.Misc.Botnick тоже можно не передавать, тогда будет записана пустая строка
|
|
||||||
// j.Misc.Csign если нам его не передали, возьмём значение из конфига
|
|
||||||
if exist := j.Misc.Csign; exist == "" {
|
|
||||||
j.Misc.Csign = config.Csign
|
|
||||||
}
|
|
||||||
|
|
||||||
// j.Misc.Fwdcnt если нам его не передали, то будет 0
|
|
||||||
if exist := j.Misc.Fwdcnt; exist == 0 {
|
|
||||||
j.Misc.Fwdcnt = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// j.Misc.GoodMorning может быть быть 1 или 0, по-умолчанию 0
|
|
||||||
// j.Misc.Msgformat может быть быть 1 или 0, по-умолчанию 0
|
|
||||||
// j.Misc.Username можно не передавать, тогда будет пустая строка
|
|
||||||
|
|
||||||
// Отвалидировались, теперь вернёмся к нашим баранам.
|
|
||||||
|
|
||||||
// Если у нас циклическая пересылка сообщения, попробуем её тут разорвать, отбросив сообщение
|
|
||||||
if j.Misc.Fwdcnt > config.ForwardsMax {
|
|
||||||
log.Warnf("Discarding msg with fwd_cnt exceeding max value: %s", msg)
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
j.Misc.Fwdcnt++
|
|
||||||
}
|
|
||||||
|
|
||||||
// Классифицирем входящие сообщения. Первым делом, попробуем определить команды
|
|
||||||
if j.Message[0:len(j.Misc.Csign)] == j.Misc.Csign {
|
|
||||||
// Может быть, это команда модуля phrases?
|
|
||||||
var done = false
|
|
||||||
var cmd = j.Message[len(j.Misc.Csign):]
|
|
||||||
cmds := []string{"friday", "пятница", "proverb", "пословица", "fortune", "фортунка", "f", "ф", "karma", "карма",
|
|
||||||
"rum", "ром", "vodka", "водка", "beer", "пиво", "tequila", "текила", "whisky", "виски", "absinthe",
|
|
||||||
"абсент"}
|
|
||||||
|
|
||||||
for _, command := range cmds {
|
|
||||||
if cmd == command {
|
|
||||||
sendTo = "phrases"
|
|
||||||
|
|
||||||
// Костыль для кармы
|
|
||||||
if cmd == "karma" || cmd == "карма" {
|
|
||||||
j.Misc.Answer = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
done = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Не угадали? акей, как насчёт модуля webapp?
|
|
||||||
if !done {
|
|
||||||
cmds = []string{"buni", "anek", "анек", "анекдот", "cat", "кис", "drink", "праздник", "fox", "лис", "frog",
|
|
||||||
"лягушка", "horse", "лошадь", "лошадка", "monkeyuser", "rabbit", "bunny", "кролик", "snail", "улитка",
|
|
||||||
"owl", "сова", "сыч", "xkcd", "tits", "boobs", "tities", "boobies", "сиси", "сисечки", "butt", "booty",
|
|
||||||
"ass", "попа", "попка"}
|
|
||||||
|
|
||||||
for _, command := range cmds {
|
|
||||||
if cmd == command {
|
|
||||||
sendTo = "webapp"
|
|
||||||
done = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Не фортануло? может, повезёт с модулем games?
|
|
||||||
if !done {
|
|
||||||
cmds = []string{"dig", "копать", "fish", "fishing", "рыба", "рыбка", "рыбалка"}
|
|
||||||
|
|
||||||
for _, command := range cmds {
|
|
||||||
if cmd == command {
|
|
||||||
sendTo = "games"
|
|
||||||
done = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Нет? Вдруг это комплексная команда модуля webapp?
|
|
||||||
if !done {
|
|
||||||
cmdLen := len(cmd)
|
|
||||||
|
|
||||||
cmds := []string{"w ", "п ", "погода ", "погодка ", "погадка ", "weather "}
|
|
||||||
|
|
||||||
for _, command := range cmds {
|
|
||||||
if cmdLen > len(command) && cmd[0:len(command)] == command {
|
|
||||||
sendTo = "webapp"
|
|
||||||
done = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Опять мимо? Давай тогда попытаем удачу в поиске комплексной команды для phrases
|
|
||||||
if !done {
|
|
||||||
cmdLen := len(cmd)
|
|
||||||
|
|
||||||
cmds := []string{"karma ", "карма ", "rum ", "ром ", "vodka ", "водка ", "beer ", "пиво ", "tequila ",
|
|
||||||
"текила ", "whisky ", "виски ", "absinthe ", "абсент "}
|
|
||||||
|
|
||||||
for _, command := range cmds {
|
|
||||||
if cmdLen > len(command) && cmd[0:len(command)] == command {
|
|
||||||
sendTo = "phrases"
|
|
||||||
|
|
||||||
if command == "karma " || command == "карма " {
|
|
||||||
// Костыль для кармы
|
|
||||||
j.Misc.Answer = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Попробуем выискать изменение кармы
|
|
||||||
msgLen := len(j.Message)
|
|
||||||
|
|
||||||
// ++ или -- на конце фразы - это наш кандидат
|
|
||||||
if msgLen > len("++") {
|
|
||||||
if j.Message[msgLen-len("--"):msgLen] == "--" || j.Message[msgLen-len("++"):msgLen] == "++" {
|
|
||||||
// Предполагается, что менять карму мы будем для одной фразы, то есть для 1 строки
|
|
||||||
if len(strings.Split(j.Message, "\n")) == 1 {
|
|
||||||
sendTo = "phrases"
|
|
||||||
|
|
||||||
// Костыль для кармы
|
|
||||||
j.Misc.Answer = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Настало время формировать json и засылать его в дальше
|
|
||||||
var message sMsg
|
|
||||||
message.From = j.From
|
|
||||||
message.Userid = j.Userid
|
|
||||||
message.Chatid = j.Chatid
|
|
||||||
message.Message = j.Message
|
|
||||||
message.Plugin = j.Plugin
|
|
||||||
message.Mode = j.Mode
|
|
||||||
message.Misc.Fwdcnt = j.Misc.Fwdcnt
|
|
||||||
message.Misc.Csign = j.Misc.Csign
|
|
||||||
message.Misc.Username = j.Misc.Username
|
|
||||||
message.Misc.Answer = j.Misc.Answer
|
|
||||||
message.Misc.Botnick = j.Misc.Botnick
|
|
||||||
message.Misc.Msgformat = j.Misc.Msgformat
|
|
||||||
message.Misc.GoodMorning = j.Misc.GoodMorning
|
|
||||||
|
|
||||||
data, err := json.Marshal(message)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("Unable to to serialize message for redis: %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Заталкиваем наш json в редиску
|
|
||||||
if err := redisClient.Publish(ctx, sendTo, data).Err(); err != nil {
|
|
||||||
log.Warnf("Unable to send data to redis channel %s: %s", sendTo, err)
|
|
||||||
} else {
|
|
||||||
log.Debugf("Send msg to redis channel %s: %s", sendTo, string(data))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Читает и валидирует конфиг, а также выставляет некоторые default-ы, если значений для параметров в конфиге нет
|
|
||||||
func readConfig() {
|
|
||||||
configLoaded := false
|
|
||||||
executablePath, err := os.Executable()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Unable to get current executable path: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
configJSONPath := fmt.Sprintf("%s/data/config.json", filepath.Dir(executablePath))
|
|
||||||
|
|
||||||
locations := []string{
|
|
||||||
"~/.aleesa-misc-go.json",
|
|
||||||
"~/aleesa-misc-go.json",
|
|
||||||
"/etc/aleesa-misc-go.json",
|
|
||||||
configJSONPath,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, location := range locations {
|
|
||||||
fileInfo, err := os.Stat(location)
|
|
||||||
|
|
||||||
// Предполагаем, что файла либо нет, либо мы не можем его прочитать, второе надо бы логгировать, но пока забьём
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Конфиг-файл длинноват для конфига, попробуем следующего кандидата
|
|
||||||
if fileInfo.Size() > 65535 {
|
|
||||||
log.Warnf("Config file %s is too long for config, skipping", location)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
buf, err := ioutil.ReadFile(location)
|
|
||||||
|
|
||||||
// Не удалось прочитать, попробуем следующего кандидата
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("Skip reading config file %s: %s", location, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Исходя из документации, hjson какбы умеет парсить "кривой" json, но парсит его в map-ку.
|
|
||||||
// Интереснее на выходе получить структурку: то есть мы вначале конфиг преобразуем в map-ку, затем эту map-ку
|
|
||||||
// сериализуем в json, а потом json преврщааем в стркутурку. Не очень эффективно, но он и не часто требуется.
|
|
||||||
var sampleConfig myConfig
|
|
||||||
var tmp map[string]interface{}
|
|
||||||
err = hjson.Unmarshal(buf, &tmp)
|
|
||||||
|
|
||||||
// Не удалось распарсить - попробуем следующего кандидата
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("Skip parsing config file %s: %s", location, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpjson, err := json.Marshal(tmp)
|
|
||||||
|
|
||||||
// Не удалось преобразовать map-ку в json
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("Skip parsing config file %s: %s", location, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := json.Unmarshal(tmpjson, &sampleConfig); err != nil {
|
|
||||||
log.Warnf("Skip parsing config file %s: %s", location, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Валидируем значения из конфига
|
|
||||||
if sampleConfig.Server == "" {
|
|
||||||
sampleConfig.Server = "localhost"
|
|
||||||
}
|
|
||||||
|
|
||||||
if sampleConfig.Port == 0 {
|
|
||||||
sampleConfig.Port = 6379
|
|
||||||
}
|
|
||||||
|
|
||||||
if sampleConfig.Loglevel == "" {
|
|
||||||
sampleConfig.Loglevel = "info"
|
|
||||||
}
|
|
||||||
|
|
||||||
// sampleConfig.Log = "" if not set
|
|
||||||
|
|
||||||
if sampleConfig.Channel == "" {
|
|
||||||
log.Errorf("Channel field in config file %s must be set", location)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Частичная проверка, ровно то, куда мы _точно_ щепрввляем сообщения исходя из бизнес-логики приложения
|
|
||||||
if sampleConfig.ForwardChannels.Games == "" {
|
|
||||||
sampleConfig.ForwardChannels.Games = "games"
|
|
||||||
}
|
|
||||||
|
|
||||||
if sampleConfig.ForwardChannels.Phrases == "" {
|
|
||||||
sampleConfig.ForwardChannels.Phrases = "phrases"
|
|
||||||
}
|
|
||||||
|
|
||||||
if sampleConfig.ForwardChannels.Webapp == "" {
|
|
||||||
sampleConfig.ForwardChannels.Webapp = "webapp"
|
|
||||||
}
|
|
||||||
|
|
||||||
if sampleConfig.ForwardChannels.Craniac == "" {
|
|
||||||
sampleConfig.ForwardChannels.Craniac = "craniac"
|
|
||||||
}
|
|
||||||
|
|
||||||
if sampleConfig.Csign == "" {
|
|
||||||
log.Errorf("Csign field in config file %s must be set", location)
|
|
||||||
}
|
|
||||||
|
|
||||||
if sampleConfig.ForwardsMax == 0 {
|
|
||||||
sampleConfig.ForwardsMax = forwardMax
|
|
||||||
}
|
|
||||||
|
|
||||||
config = sampleConfig
|
|
||||||
configLoaded = true
|
|
||||||
log.Infof("Using %s as config file", location)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if !configLoaded {
|
|
||||||
log.Error("Config was not loaded! Refusing to start.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Хэндлер сигналов закрывает все бд и сваливает из приложения
|
|
||||||
func sigHandler() {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
for {
|
|
||||||
var s = <-sigChan
|
|
||||||
switch s {
|
|
||||||
case syscall.SIGINT:
|
|
||||||
log.Infoln("Got SIGINT, quitting")
|
|
||||||
case syscall.SIGTERM:
|
|
||||||
log.Infoln("Got SIGTERM, quitting")
|
|
||||||
case syscall.SIGQUIT:
|
|
||||||
log.Infoln("Got SIGQUIT, quitting")
|
|
||||||
|
|
||||||
// Заходим на новую итерацию, если у нас "неинтересный" сигнал
|
|
||||||
default:
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Чтобы не срать в логи ошибками от редиски, проставим shutdown state приложения в true
|
|
||||||
shutdown = true
|
|
||||||
|
|
||||||
// Отпишемся от всех каналов и закроем коннект к редиске
|
|
||||||
if err = subscriber.Unsubscribe(ctx); err != nil {
|
|
||||||
log.Errorf("Unable to unsubscribe from redis channels cleanly: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = subscriber.Close(); err != nil {
|
|
||||||
log.Errorf("Unable to close redis connection cleanly: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
|
||||||
65
cmd/aleesa-misc-go/main.go
Normal file
65
cmd/aleesa-misc-go/main.go
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"aleesa-misc-go/internal/log"
|
||||||
|
"aleesa-misc-go/internal/misc"
|
||||||
|
|
||||||
|
"github.com/go-redis/redis/v8"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
logfile *os.File
|
||||||
|
)
|
||||||
|
|
||||||
|
misc.ReadConfig()
|
||||||
|
|
||||||
|
if misc.Config.Log != "" {
|
||||||
|
logfile, err = os.OpenFile(misc.Config.Log, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error(fmt.Sprintf("Unable to open log file %s: %s", misc.Config.Log, err))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logfile = os.Stderr
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Init(misc.Config.Loglevel, logfile)
|
||||||
|
|
||||||
|
// Иницализируем клиента Редиски.
|
||||||
|
misc.RedisClient = redis.NewClient(&redis.Options{
|
||||||
|
Addr: fmt.Sprintf("%s:%d", misc.Config.Server, misc.Config.Port),
|
||||||
|
}).WithContext(misc.Ctx).WithTimeout(time.Duration(misc.Config.Timeout) * time.Second)
|
||||||
|
|
||||||
|
// Обозначим, что хотим после соединения подписаться на события из канала config.Channel.
|
||||||
|
misc.Subscriber = misc.RedisClient.Subscribe(misc.Ctx, misc.Config.Channel)
|
||||||
|
|
||||||
|
// Самое время поставить траппер сигналов.
|
||||||
|
signal.Notify(misc.SigChan,
|
||||||
|
syscall.SIGINT,
|
||||||
|
syscall.SIGTERM,
|
||||||
|
syscall.SIGQUIT)
|
||||||
|
|
||||||
|
go misc.SigHandler()
|
||||||
|
|
||||||
|
// Начнём выгребать события из редиски (длина конвеера/буфера канала по-умолчанию - 100 сообщений).
|
||||||
|
ch := misc.Subscriber.Channel()
|
||||||
|
|
||||||
|
log.Info("Aleesa-misc-go started")
|
||||||
|
|
||||||
|
for msg := range ch {
|
||||||
|
if !misc.Shutdown {
|
||||||
|
misc.MsgParser(misc.Ctx, msg.Payload)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||||
@@ -5,6 +5,9 @@
|
|||||||
# 6379 if not set
|
# 6379 if not set
|
||||||
"port" : 6379,
|
"port" : 6379,
|
||||||
|
|
||||||
|
# Redis timeout, 10 seconds if not set
|
||||||
|
"timeout" : 10,
|
||||||
|
|
||||||
# info if not set
|
# info if not set
|
||||||
"loglevel" : "info",
|
"loglevel" : "info",
|
||||||
|
|
||||||
@@ -25,6 +28,9 @@
|
|||||||
# webapp if not set
|
# webapp if not set
|
||||||
"webapp" : "webapp",
|
"webapp" : "webapp",
|
||||||
|
|
||||||
|
# webapp-go if not set
|
||||||
|
"webapp-go" : "webapp-go",
|
||||||
|
|
||||||
# craniac if not set
|
# craniac if not set
|
||||||
"craniac" : "craniac"
|
"craniac" : "craniac"
|
||||||
},
|
},
|
||||||
|
|||||||
29
globals.go
29
globals.go
@@ -1,29 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/go-redis/redis/v8"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Config - это у нас глобальная штука :)
|
|
||||||
var config myConfig
|
|
||||||
|
|
||||||
// To break circular message forwarding we must set some sane default, it can be overridden via config
|
|
||||||
var forwardMax int64 = 5
|
|
||||||
|
|
||||||
// Объектики клиента-редиски
|
|
||||||
var redisClient *redis.Client
|
|
||||||
var subscriber *redis.PubSub
|
|
||||||
|
|
||||||
// Main context
|
|
||||||
var ctx = context.Background()
|
|
||||||
|
|
||||||
// Ставится в true, если мы получили сигнал на выключение
|
|
||||||
var shutdown = false
|
|
||||||
|
|
||||||
// Канал, в который приходят уведомления для хэндлера сигналов от траппера сигналов
|
|
||||||
var sigChan = make(chan os.Signal, 1)
|
|
||||||
|
|
||||||
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
|
||||||
13
go.mod
13
go.mod
@@ -1,20 +1,13 @@
|
|||||||
module aleesa-misc-go
|
module aleesa-misc-go
|
||||||
|
|
||||||
go 1.18
|
go 1.25.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/go-redis/redis/v8 v8.11.4
|
github.com/go-redis/redis/v8 v8.11.5
|
||||||
github.com/sirupsen/logrus v1.8.1
|
github.com/hjson/hjson-go v3.3.0+incompatible
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/hjson/hjson-go v3.1.0+incompatible
|
|
||||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
|
||||||
github.com/onsi/gomega v1.18.1 // indirect
|
|
||||||
)
|
)
|
||||||
|
|||||||
99
go.sum
99
go.sum
@@ -1,117 +1,26 @@
|
|||||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
|
||||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
|
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||||
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
|
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
github.com/hjson/hjson-go v3.3.0+incompatible h1:Rqr+Ya+0aCJMjaE4s8E9YKvuJLuLVpEvz4ONum52vnI=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/hjson/hjson-go v3.3.0+incompatible/go.mod h1:qsetwF8NlsTsOTwZTApNlTCerV+b2GjYRRcIk4JMFio=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
|
||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/hjson/hjson-go v3.1.0+incompatible h1:DY/9yE8ey8Zv22bY+mHV1uk2yRy0h8tKhZ77hEdi0Aw=
|
|
||||||
github.com/hjson/hjson-go v3.1.0+incompatible/go.mod h1:qsetwF8NlsTsOTwZTApNlTCerV+b2GjYRRcIk4JMFio=
|
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
|
||||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
|
||||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
|
||||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
|
||||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||||
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
|
||||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
|
||||||
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
|
||||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
|
||||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||||
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
|
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
|
||||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
|
||||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
|
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
|
||||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
|
||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
|
||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
|
|||||||
106
internal/log/log.go
Normal file
106
internal/log/log.go
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
package log
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Init setup logger stuff.
|
||||||
|
// level can be error, warn, info, debug if something other supplied info level selected.
|
||||||
|
// fileDescriptor should be opened before supplying it to Init().
|
||||||
|
func Init(level string, fileDescriptor *os.File) {
|
||||||
|
var loglevel slog.Level
|
||||||
|
|
||||||
|
// no panic, no trace.
|
||||||
|
switch level {
|
||||||
|
case "error":
|
||||||
|
loglevel = slog.LevelError
|
||||||
|
|
||||||
|
case "warn":
|
||||||
|
loglevel = slog.LevelWarn
|
||||||
|
|
||||||
|
case "info":
|
||||||
|
loglevel = slog.LevelInfo
|
||||||
|
|
||||||
|
case "debug":
|
||||||
|
loglevel = slog.LevelDebug
|
||||||
|
|
||||||
|
default:
|
||||||
|
loglevel = slog.LevelInfo
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := &slog.HandlerOptions{
|
||||||
|
// Use the ReplaceAttr function on the handler options
|
||||||
|
// to be able to replace any single attribute in the log output
|
||||||
|
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
|
||||||
|
// check that we are handling the time key
|
||||||
|
if a.Key != slog.TimeKey {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
t := a.Value.Time()
|
||||||
|
|
||||||
|
// change the value from a time.Time to a String
|
||||||
|
// where the string has the correct time format.
|
||||||
|
a.Value = slog.StringValue(t.Format(time.DateTime))
|
||||||
|
|
||||||
|
return a
|
||||||
|
},
|
||||||
|
|
||||||
|
Level: loglevel,
|
||||||
|
}
|
||||||
|
|
||||||
|
slog.SetDefault(
|
||||||
|
slog.New(
|
||||||
|
slog.NewTextHandler(
|
||||||
|
fileDescriptor,
|
||||||
|
opts,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error passes message directly to slog.Error().
|
||||||
|
func Error(message string) {
|
||||||
|
slog.Error(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Errorf logs message on error log level and allows to supply arguments in printf() style.
|
||||||
|
func Errorf(format string, a ...any) {
|
||||||
|
slog.Error(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warn passes message directly to slog.Warn().
|
||||||
|
func Warn(message string) {
|
||||||
|
slog.Warn(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warnf logs message on warn log level and allows to supply arguments in printf() style.
|
||||||
|
func Warnf(format string, a ...any) {
|
||||||
|
slog.Warn(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info passes message directly to slog.Info().
|
||||||
|
func Info(message string) {
|
||||||
|
slog.Info(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Infof logs message on info log level and allows to supply arguments in printf() style.
|
||||||
|
func Infof(format string, a ...any) {
|
||||||
|
slog.Info(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug passes message directly to slog.Debug().
|
||||||
|
func Debug(message string) {
|
||||||
|
slog.Debug(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debugf logs message on debug log level and allows to supply arguments in printf() style.
|
||||||
|
func Debugf(format string, a ...any) {
|
||||||
|
slog.Debug(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||||
29
internal/misc/globals.go
Normal file
29
internal/misc/globals.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package misc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/go-redis/redis/v8"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config - это у нас глобальная штука.
|
||||||
|
var Config myConfig
|
||||||
|
|
||||||
|
// To break circular message forwarding we must set some sane default, it can be overridden via config.
|
||||||
|
var ForwardMax int64 = 5
|
||||||
|
|
||||||
|
// Объектики клиента-редиски.
|
||||||
|
var RedisClient *redis.Client
|
||||||
|
var Subscriber *redis.PubSub
|
||||||
|
|
||||||
|
// Ставится в true, если мы получили сигнал на выключение.
|
||||||
|
var Shutdown = false
|
||||||
|
|
||||||
|
// Канал, в который приходят уведомления для хэндлера сигналов от траппера сигналов.
|
||||||
|
var SigChan = make(chan os.Signal, 1)
|
||||||
|
|
||||||
|
// Main context.
|
||||||
|
var Ctx = context.Background()
|
||||||
|
|
||||||
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||||
238
internal/misc/msgParser.go
Normal file
238
internal/misc/msgParser.go
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
package misc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"aleesa-misc-go/internal/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MsgParser горутинка, которая парсит json-чики прилетевшие из REDIS-ки.
|
||||||
|
func MsgParser(ctx context.Context, msg string) {
|
||||||
|
var (
|
||||||
|
sendTo = "craniac"
|
||||||
|
j rMsg
|
||||||
|
)
|
||||||
|
|
||||||
|
log.Debugf("Incomming raw json: %s", msg)
|
||||||
|
|
||||||
|
if err := json.Unmarshal([]byte(msg), &j); err != nil {
|
||||||
|
log.Warnf("Unable to to parse message from redis channel: %s", err)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate our j.
|
||||||
|
if exist := j.From; exist == "" {
|
||||||
|
log.Warnf("Incorrect msg from redis, no from field: %s", msg)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if exist := j.Chatid; exist == "" {
|
||||||
|
log.Warnf("Incorrect msg from redis, no chatid field: %s", msg)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if exist := j.Userid; exist == "" {
|
||||||
|
log.Warnf("Incorrect msg from redis, no userid field: %s", msg)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// j.Threadid может быть пустым, значит либо нам его не дали, либо дали пустым. Это нормально.
|
||||||
|
|
||||||
|
if exist := j.Message; exist == "" {
|
||||||
|
log.Warnf("Incorrect msg from redis, no message field: %s", msg)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if exist := j.Plugin; exist == "" {
|
||||||
|
log.Warnf("Incorrect msg from redis, no plugin field: %s", msg)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if exist := j.Mode; exist == "" {
|
||||||
|
log.Warnf("Incorrect msg from redis, no mode field: %s", msg)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// j.Misc.Answer может и не быть, тогда ответа на такое сообщение не будет.
|
||||||
|
// j.Misc.Botnick тоже можно не передавать, тогда будет записана пустая строка.
|
||||||
|
// j.Misc.Csign если нам его не передали, возьмём значение из конфига.
|
||||||
|
if exist := j.Misc.Csign; exist == "" {
|
||||||
|
j.Misc.Csign = Config.Csign
|
||||||
|
}
|
||||||
|
|
||||||
|
// j.Misc.Fwdcnt если нам его не передали, то будет 0.
|
||||||
|
if exist := j.Misc.Fwdcnt; exist == 0 {
|
||||||
|
j.Misc.Fwdcnt = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// j.Misc.GoodMorning может быть 1 или 0, по-умолчанию 0.
|
||||||
|
// j.Misc.Msgformat может быть 1 или 0, по-умолчанию 0.
|
||||||
|
// j.Misc.Username можно не передавать, тогда будет пустая строка.
|
||||||
|
|
||||||
|
// Отвалидировались, теперь вернёмся к нашим баранам.
|
||||||
|
|
||||||
|
// Если у нас циклическая пересылка сообщения, попробуем её тут разорвать, отбросив сообщение.
|
||||||
|
if j.Misc.Fwdcnt > Config.ForwardsMax {
|
||||||
|
log.Warnf("Discarding msg with fwd_cnt exceeding max value: %s", msg)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
j.Misc.Fwdcnt++
|
||||||
|
|
||||||
|
// Классифицирем входящие сообщения. Первым делом, попробуем определить команды.
|
||||||
|
if j.Message[0:len(j.Misc.Csign)] == j.Misc.Csign {
|
||||||
|
// Может быть, это команда модуля phrases?
|
||||||
|
var (
|
||||||
|
done = false
|
||||||
|
cmd = j.Message[len(j.Misc.Csign):]
|
||||||
|
)
|
||||||
|
|
||||||
|
cmds := []string{"friday", "пятница", "proverb", "пословица", "пословиться", "fortune", "фортунка", "f", "ф",
|
||||||
|
"karma", "карма", "rum", "ром", "vodka", "водка", "beer", "пиво", "tequila", "текила", "whisky", "виски",
|
||||||
|
"absinthe", "абсент", "fuck"}
|
||||||
|
|
||||||
|
for _, command := range cmds {
|
||||||
|
if cmd == command {
|
||||||
|
sendTo = Config.ForwardChannels.Phrases
|
||||||
|
|
||||||
|
// Костыль для кармы.
|
||||||
|
if cmd == "karma" || cmd == "карма" {
|
||||||
|
j.Misc.Answer = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
done = true
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Не угадали? акей, как насчёт модуля webapp-go?
|
||||||
|
if !done {
|
||||||
|
cmds = []string{"frog", "лягушка", "horse", "лошадь", "лошадка", "rabbit", "bunny", "кролик",
|
||||||
|
"snail", "улитка", "cat", "кис", "fox", "лис", "buni", "anek", "анек", "анекдот",
|
||||||
|
"xkcd", "monkeyuser", "tits", "boobs", "tities", "boobies", "сиси", "сисечки", "butt",
|
||||||
|
"booty", "ass", "попа", "попка", "drink", "праздник", "owl", "сова", "сыч", "w", "п", "погода",
|
||||||
|
"погодка", "погадка"}
|
||||||
|
|
||||||
|
for _, command := range cmds {
|
||||||
|
if cmd == command {
|
||||||
|
sendTo = Config.ForwardChannels.WebappGo
|
||||||
|
done = true
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Не фортануло? может, повезёт с модулем games?
|
||||||
|
if !done {
|
||||||
|
cmds = []string{"dig", "копать", "fish", "fishing", "рыба", "рыбка", "рыбалка"}
|
||||||
|
|
||||||
|
for _, command := range cmds {
|
||||||
|
if cmd == command {
|
||||||
|
sendTo = Config.ForwardChannels.Games
|
||||||
|
done = true
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Нет? Вдруг это комплексная команда модуля webapp?
|
||||||
|
if !done {
|
||||||
|
cmdLen := len(cmd)
|
||||||
|
|
||||||
|
cmds := []string{"w ", "п ", "погода ", "погодка ", "погадка ", "weather "}
|
||||||
|
|
||||||
|
for _, command := range cmds {
|
||||||
|
if cmdLen > len(command) && cmd[0:len(command)] == command {
|
||||||
|
sendTo = Config.ForwardChannels.WebappGo
|
||||||
|
done = true
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Опять мимо? Давай тогда попытаем удачу в поиске комплексной команды для phrases.
|
||||||
|
if !done {
|
||||||
|
cmdLen := len(cmd)
|
||||||
|
|
||||||
|
cmds := []string{"karma ", "карма ", "rum ", "ром ", "vodka ", "водка ", "beer ", "пиво ", "tequila ",
|
||||||
|
"текила ", "whisky ", "виски ", "absinthe ", "абсент "}
|
||||||
|
|
||||||
|
for _, command := range cmds {
|
||||||
|
if cmdLen > len(command) && cmd[0:len(command)] == command {
|
||||||
|
sendTo = Config.ForwardChannels.Phrases
|
||||||
|
|
||||||
|
if command == "karma " || command == "карма " {
|
||||||
|
// Костыль для кармы
|
||||||
|
j.Misc.Answer = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Попробуем выискать изменение кармы.
|
||||||
|
msgLen := len(j.Message)
|
||||||
|
|
||||||
|
// ++ или -- на конце фразы - это наш кандидат.
|
||||||
|
if msgLen > len("++") {
|
||||||
|
if j.Message[msgLen-len("--"):msgLen] == "--" || j.Message[msgLen-len("++"):msgLen] == "++" {
|
||||||
|
// Предполагается, что менять карму мы будем для одной фразы, то есть для 1 строки
|
||||||
|
if len(strings.Split(j.Message, "\n")) == 1 {
|
||||||
|
sendTo = Config.ForwardChannels.Phrases
|
||||||
|
|
||||||
|
// Костыль для кармы
|
||||||
|
j.Misc.Answer = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Настало время формировать json и засылать его в дальше.
|
||||||
|
var message sMsg
|
||||||
|
message.From = j.From
|
||||||
|
message.Userid = j.Userid
|
||||||
|
message.Chatid = j.Chatid
|
||||||
|
message.Threadid = j.Threadid
|
||||||
|
message.Message = j.Message
|
||||||
|
message.Plugin = j.Plugin
|
||||||
|
message.Mode = j.Mode
|
||||||
|
message.Misc.Fwdcnt = j.Misc.Fwdcnt
|
||||||
|
message.Misc.Csign = j.Misc.Csign
|
||||||
|
message.Misc.Username = j.Misc.Username
|
||||||
|
message.Misc.Answer = j.Misc.Answer
|
||||||
|
message.Misc.Botnick = j.Misc.Botnick
|
||||||
|
message.Misc.Msgformat = j.Misc.Msgformat
|
||||||
|
message.Misc.GoodMorning = j.Misc.GoodMorning
|
||||||
|
|
||||||
|
data, err := json.Marshal(message)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("Unable to to serialize message for redis: %s", err)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Заталкиваем наш json в редиску.
|
||||||
|
if err := RedisClient.Publish(ctx, sendTo, data).Err(); err != nil {
|
||||||
|
log.Warnf("Unable to send data to redis channel %s: %s", sendTo, err)
|
||||||
|
} else {
|
||||||
|
log.Debugf("Send msg to redis channel %s: %s", sendTo, string(data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||||
155
internal/misc/readConfig.go
Normal file
155
internal/misc/readConfig.go
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
package misc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"aleesa-misc-go/internal/log"
|
||||||
|
|
||||||
|
"github.com/hjson/hjson-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ReadConfig читает и валидирует конфиг, а также выставляет некоторые default-ы, если значений для параметров в конфиге
|
||||||
|
// нет.
|
||||||
|
func ReadConfig() {
|
||||||
|
configLoaded := false
|
||||||
|
executablePath, err := os.Executable()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Unable to get current executable path: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
configJSONPath := fmt.Sprintf("%s/data/config.json", filepath.Dir(executablePath))
|
||||||
|
|
||||||
|
locations := []string{
|
||||||
|
"~/.aleesa-misc-go.json",
|
||||||
|
"~/aleesa-misc-go.json",
|
||||||
|
"/etc/aleesa-misc-go.json",
|
||||||
|
configJSONPath,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, location := range locations {
|
||||||
|
fileInfo, err := os.Stat(location)
|
||||||
|
|
||||||
|
// Предполагаем, что файла либо нет, либо мы не можем его прочитать, второе надо бы логгировать, но пока забьём
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Конфиг-файл длинноват для конфига, попробуем следующего кандидата
|
||||||
|
if fileInfo.Size() > 65535 {
|
||||||
|
log.Warnf("Config file %s is too long for config, skipping", location)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := os.ReadFile(location)
|
||||||
|
|
||||||
|
// Не удалось прочитать, попробуем следующего кандидата
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("Skip reading config file %s: %s", location, err)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Исходя из документации, hjson какбы умеет парсить "кривой" json, но парсит его в map-ку.
|
||||||
|
// Интереснее на выходе получить структурку: то есть мы вначале конфиг преобразуем в map-ку, затем эту map-ку
|
||||||
|
// сериализуем в json, а потом json преврщааем в стркутурку. Не очень эффективно, но он и не часто требуется.
|
||||||
|
var (
|
||||||
|
sampleConfig myConfig
|
||||||
|
tmp map[string]interface{}
|
||||||
|
)
|
||||||
|
|
||||||
|
err = hjson.Unmarshal(buf, &tmp)
|
||||||
|
|
||||||
|
// Не удалось распарсить - попробуем следующего кандидата
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("Skip parsing config file %s: %s", location, err)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpjson, err := json.Marshal(tmp)
|
||||||
|
|
||||||
|
// Не удалось преобразовать map-ку в json
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("Skip parsing config file %s: %s", location, err)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(tmpjson, &sampleConfig); err != nil {
|
||||||
|
log.Warnf("Skip parsing config file %s: %s", location, err)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Валидируем значения из конфига
|
||||||
|
if sampleConfig.Server == "" {
|
||||||
|
sampleConfig.Server = "localhost"
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.Port == 0 {
|
||||||
|
sampleConfig.Port = 6379
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.Timeout == 0 {
|
||||||
|
sampleConfig.Timeout = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.Loglevel == "" {
|
||||||
|
sampleConfig.Loglevel = "info"
|
||||||
|
}
|
||||||
|
|
||||||
|
// sampleConfig.Log = "" if not set
|
||||||
|
|
||||||
|
if sampleConfig.Channel == "" {
|
||||||
|
log.Errorf("Channel field in config file %s must be set", location)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Частичная проверка, ровно то, куда мы _точно_ щепрввляем сообщения исходя из бизнес-логики приложения
|
||||||
|
if sampleConfig.ForwardChannels.Games == "" {
|
||||||
|
sampleConfig.ForwardChannels.Games = "games"
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.ForwardChannels.Phrases == "" {
|
||||||
|
sampleConfig.ForwardChannels.Phrases = "phrases"
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.ForwardChannels.Webapp == "" {
|
||||||
|
sampleConfig.ForwardChannels.Webapp = "webapp"
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.ForwardChannels.WebappGo == "" {
|
||||||
|
sampleConfig.ForwardChannels.WebappGo = "webapp-go"
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.ForwardChannels.Craniac == "" {
|
||||||
|
sampleConfig.ForwardChannels.Craniac = "craniac"
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.Csign == "" {
|
||||||
|
log.Errorf("Csign field in config file %s must be set", location)
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.ForwardsMax == 0 {
|
||||||
|
sampleConfig.ForwardsMax = ForwardMax
|
||||||
|
}
|
||||||
|
|
||||||
|
Config = sampleConfig
|
||||||
|
configLoaded = true
|
||||||
|
|
||||||
|
log.Infof("Using %s as config file", location)
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if !configLoaded {
|
||||||
|
log.Error("Config was not loaded! Refusing to start.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||||
47
internal/misc/sigHandler.go
Normal file
47
internal/misc/sigHandler.go
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package misc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"aleesa-misc-go/internal/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SigHandler хэндлер сигналов закрывает все бд и сваливает из приложения.
|
||||||
|
func SigHandler() {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
log.Info("Install signal handler")
|
||||||
|
|
||||||
|
for {
|
||||||
|
var s = <-SigChan
|
||||||
|
switch s {
|
||||||
|
case syscall.SIGINT:
|
||||||
|
log.Info("Got SIGINT, quitting")
|
||||||
|
case syscall.SIGTERM:
|
||||||
|
log.Info("Got SIGTERM, quitting")
|
||||||
|
case syscall.SIGQUIT:
|
||||||
|
log.Info("Got SIGQUIT, quitting")
|
||||||
|
|
||||||
|
// Заходим на новую итерацию, если у нас "неинтересный" сигнал.
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Чтобы не срать в логи ошибками от редиски, проставим shutdown state приложения в true.
|
||||||
|
Shutdown = true
|
||||||
|
|
||||||
|
// Отпишемся от всех каналов и закроем коннект к редиске.
|
||||||
|
if err = Subscriber.Unsubscribe(Ctx); err != nil {
|
||||||
|
log.Errorf("Unable to unsubscribe from redis channels cleanly: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = Subscriber.Close(); err != nil {
|
||||||
|
log.Errorf("Unable to close redis connection cleanly: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||||
62
internal/misc/types.go
Normal file
62
internal/misc/types.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package misc
|
||||||
|
|
||||||
|
// myConfig структура, описывающая формат Конфига приложения.
|
||||||
|
type myConfig struct {
|
||||||
|
Server string `json:"server,omitempty"`
|
||||||
|
Port int `json:"port,omitempty"`
|
||||||
|
Timeout int `json:"timeout,omitempty"`
|
||||||
|
Loglevel string `json:"loglevel,omitempty"`
|
||||||
|
Log string `json:"log,omitempty"`
|
||||||
|
Channel string `json:"channel,omitempty"`
|
||||||
|
ForwardChannels struct {
|
||||||
|
Games string `json:"games,omitempty"`
|
||||||
|
Phrases string `json:"phrases,omitempty"`
|
||||||
|
Webapp string `json:"webapp,omitempty"`
|
||||||
|
WebappGo string `json:"webapp-go,omitempty"`
|
||||||
|
Craniac string `json:"craniac,omitempty"`
|
||||||
|
} `json:"forward_channels"`
|
||||||
|
Csign string `json:"csign,omitempty"`
|
||||||
|
ForwardsMax int64 `json:"forwards_max,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// sMsg структура, описывающая формат исходящего сообщения в pubsub-канал redis-ки.
|
||||||
|
type sMsg struct {
|
||||||
|
From string `json:"from"`
|
||||||
|
Chatid string `json:"chatid"`
|
||||||
|
Userid string `json:"userid"`
|
||||||
|
Threadid string `json:"threadid"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Plugin string `json:"plugin"`
|
||||||
|
Mode string `json:"mode"`
|
||||||
|
Misc struct {
|
||||||
|
Answer int64 `json:"answer"`
|
||||||
|
Botnick string `json:"bot_nick"`
|
||||||
|
Csign string `json:"csign"`
|
||||||
|
Fwdcnt int64 `json:"fwd_cnt"`
|
||||||
|
GoodMorning int64 `json:"good_morning"`
|
||||||
|
Msgformat int64 `json:"msg_format"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
} `json:"misc"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// rMsg структура, описывающая формат входящего сообщения из pubsub-канала redis-ки.
|
||||||
|
type rMsg struct {
|
||||||
|
From string `json:"from,omitempty"`
|
||||||
|
Chatid string `json:"chatid,omitempty"`
|
||||||
|
Userid string `json:"userid,omitempty"`
|
||||||
|
Threadid string `json:"threadid,omitempty"`
|
||||||
|
Message string `json:"message,omitempty"`
|
||||||
|
Plugin string `json:"plugin,omitempty"`
|
||||||
|
Mode string `json:"mode,omitempty"`
|
||||||
|
Misc struct {
|
||||||
|
Answer int64 `json:"answer,omitempty"`
|
||||||
|
Botnick string `json:"bot_nick,omitempty"`
|
||||||
|
Csign string `json:"csign,omitempty"`
|
||||||
|
Fwdcnt int64 `json:"fwd_cnt,omitempty"`
|
||||||
|
GoodMorning int64 `json:"good_morning,omitempty"`
|
||||||
|
Msgformat int64 `json:"msg_format,omitempty"`
|
||||||
|
Username string `json:"username,omitempty"`
|
||||||
|
} `json:"Misc"`
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||||
98
main.go
98
main.go
@@ -1,98 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/go-redis/redis/v8"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Производит некоторую инициализацию перед запуском main()
|
|
||||||
func init() {
|
|
||||||
log.SetFormatter(&log.TextFormatter{
|
|
||||||
DisableQuote: true,
|
|
||||||
DisableLevelTruncation: false,
|
|
||||||
DisableColors: true,
|
|
||||||
FullTimestamp: true,
|
|
||||||
TimestampFormat: "2006-01-02 15:04:05",
|
|
||||||
})
|
|
||||||
|
|
||||||
readConfig()
|
|
||||||
|
|
||||||
// no panic, no trace
|
|
||||||
switch config.Loglevel {
|
|
||||||
case "fatal":
|
|
||||||
log.SetLevel(log.FatalLevel)
|
|
||||||
case "error":
|
|
||||||
log.SetLevel(log.ErrorLevel)
|
|
||||||
case "warn":
|
|
||||||
log.SetLevel(log.WarnLevel)
|
|
||||||
case "info":
|
|
||||||
log.SetLevel(log.InfoLevel)
|
|
||||||
case "debug":
|
|
||||||
log.SetLevel(log.DebugLevel)
|
|
||||||
default:
|
|
||||||
log.SetLevel(log.InfoLevel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Основная функция программы, не добавить и не убавить
|
|
||||||
func main() {
|
|
||||||
// Main context
|
|
||||||
var ctx = context.Background()
|
|
||||||
|
|
||||||
// Откроем лог и скормим его логгеру
|
|
||||||
if config.Log != "" {
|
|
||||||
logfile, err := os.OpenFile(config.Log, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Unable to open log file %s: %s", config.Log, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.SetOutput(logfile)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Иницализируем клиента
|
|
||||||
redisClient = redis.NewClient(&redis.Options{
|
|
||||||
Addr: fmt.Sprintf("%s:%d", config.Server, config.Port),
|
|
||||||
})
|
|
||||||
|
|
||||||
log.Debugf("Lazy connect() to redis at %s:%d", config.Server, config.Port)
|
|
||||||
subscriber = redisClient.Subscribe(ctx, config.Channel)
|
|
||||||
|
|
||||||
// Самое время поставить траппер сигналов
|
|
||||||
signal.Notify(sigChan,
|
|
||||||
syscall.SIGINT,
|
|
||||||
syscall.SIGTERM,
|
|
||||||
syscall.SIGQUIT)
|
|
||||||
|
|
||||||
go sigHandler()
|
|
||||||
|
|
||||||
// Обработчик событий от редиски
|
|
||||||
for {
|
|
||||||
if shutdown {
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
msg, err := subscriber.ReceiveMessage(ctx)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
if !shutdown {
|
|
||||||
log.Warnf("Unable to connect to redis at %s:%d: %s", config.Server, config.Port, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
go msgParser(ctx, msg.Payload)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
|
||||||
58
types.go
58
types.go
@@ -1,58 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
// Конфиг
|
|
||||||
type myConfig struct {
|
|
||||||
Server string `json:"server,omitempty"`
|
|
||||||
Port int `json:"port,omitempty"`
|
|
||||||
Loglevel string `json:"loglevel,omitempty"`
|
|
||||||
Log string `json:"log,omitempty"`
|
|
||||||
Channel string `json:"channel,omitempty"`
|
|
||||||
ForwardChannels struct {
|
|
||||||
Games string `json:"games,omitempty"`
|
|
||||||
Phrases string `json:"phrases,omitempty"`
|
|
||||||
Webapp string `json:"webapp,omitempty"`
|
|
||||||
Craniac string `json:"craniac,omitempty"`
|
|
||||||
} `json:"forward_channels"`
|
|
||||||
Csign string `json:"csign,omitempty"`
|
|
||||||
ForwardsMax int64 `json:"forwards_max,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Входящее сообщение из pubsub-канала redis-ки
|
|
||||||
type rMsg struct {
|
|
||||||
From string `json:"from,omitempty"`
|
|
||||||
Chatid string `json:"chatid,omitempty"`
|
|
||||||
Userid string `json:"userid,omitempty"`
|
|
||||||
Message string `json:"message,omitempty"`
|
|
||||||
Plugin string `json:"plugin,omitempty"`
|
|
||||||
Mode string `json:"mode,omitempty"`
|
|
||||||
Misc struct {
|
|
||||||
Answer int64 `json:"answer,omitempty"`
|
|
||||||
Botnick string `json:"bot_nick,omitempty"`
|
|
||||||
Csign string `json:"csign,omitempty"`
|
|
||||||
Fwdcnt int64 `json:"fwd_cnt,omitempty"`
|
|
||||||
GoodMorning int64 `json:"good_morning,omitempty"`
|
|
||||||
Msgformat int64 `json:"msg_format,omitempty"`
|
|
||||||
Username string `json:"username,omitempty"`
|
|
||||||
} `json:"Misc"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Исходящее сообщение в pubsub-канал redis-ки
|
|
||||||
type sMsg struct {
|
|
||||||
From string `json:"from"`
|
|
||||||
Chatid string `json:"chatid"`
|
|
||||||
Userid string `json:"userid"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
Plugin string `json:"plugin"`
|
|
||||||
Mode string `json:"mode"`
|
|
||||||
Misc struct {
|
|
||||||
Answer int64 `json:"answer"`
|
|
||||||
Botnick string `json:"bot_nick"`
|
|
||||||
Csign string `json:"csign"`
|
|
||||||
Fwdcnt int64 `json:"fwd_cnt"`
|
|
||||||
GoodMorning int64 `json:"good_morning"`
|
|
||||||
Msgformat int64 `json:"msg_format"`
|
|
||||||
Username string `json:"username"`
|
|
||||||
} `json:"misc"`
|
|
||||||
}
|
|
||||||
|
|
||||||
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
|
||||||
23
vendor/github.com/go-redis/redis/v8/.golangci.yml
generated
vendored
23
vendor/github.com/go-redis/redis/v8/.golangci.yml
generated
vendored
@@ -2,26 +2,3 @@ run:
|
|||||||
concurrency: 8
|
concurrency: 8
|
||||||
deadline: 5m
|
deadline: 5m
|
||||||
tests: false
|
tests: false
|
||||||
linters:
|
|
||||||
enable-all: true
|
|
||||||
disable:
|
|
||||||
- funlen
|
|
||||||
- gochecknoglobals
|
|
||||||
- gochecknoinits
|
|
||||||
- gocognit
|
|
||||||
- goconst
|
|
||||||
- godox
|
|
||||||
- gosec
|
|
||||||
- maligned
|
|
||||||
- wsl
|
|
||||||
- gomnd
|
|
||||||
- goerr113
|
|
||||||
- exhaustive
|
|
||||||
- nestif
|
|
||||||
- nlreturn
|
|
||||||
- exhaustivestruct
|
|
||||||
- wrapcheck
|
|
||||||
- errorlint
|
|
||||||
- cyclop
|
|
||||||
- forcetypeassert
|
|
||||||
- forbidigo
|
|
||||||
|
|||||||
28
vendor/github.com/go-redis/redis/v8/CHANGELOG.md
generated
vendored
28
vendor/github.com/go-redis/redis/v8/CHANGELOG.md
generated
vendored
@@ -1,3 +1,31 @@
|
|||||||
|
## [8.11.5](https://github.com/go-redis/redis/compare/v8.11.4...v8.11.5) (2022-03-17)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* add missing Expire methods to Cmdable ([17e3b43](https://github.com/go-redis/redis/commit/17e3b43879d516437ada71cf9c0deac6a382ed9a))
|
||||||
|
* add whitespace for avoid unlikely colisions ([7f7c181](https://github.com/go-redis/redis/commit/7f7c1817617cfec909efb13d14ad22ef05a6ad4c))
|
||||||
|
* example/otel compile error ([#2028](https://github.com/go-redis/redis/issues/2028)) ([187c07c](https://github.com/go-redis/redis/commit/187c07c41bf68dc3ab280bc3a925e960bbef6475))
|
||||||
|
* **extra/redisotel:** set span.kind attribute to client ([065b200](https://github.com/go-redis/redis/commit/065b200070b41e6e949710b4f9e01b50ccc60ab2))
|
||||||
|
* format ([96f53a0](https://github.com/go-redis/redis/commit/96f53a0159a28affa94beec1543a62234e7f8b32))
|
||||||
|
* invalid type assert in stringArg ([de6c131](https://github.com/go-redis/redis/commit/de6c131865b8263400c8491777b295035f2408e4))
|
||||||
|
* rename Golang to Go ([#2030](https://github.com/go-redis/redis/issues/2030)) ([b82a2d9](https://github.com/go-redis/redis/commit/b82a2d9d4d2de7b7cbe8fcd4895be62dbcacacbc))
|
||||||
|
* set timeout for WAIT command. Fixes [#1963](https://github.com/go-redis/redis/issues/1963) ([333fee1](https://github.com/go-redis/redis/commit/333fee1a8fd98a2fbff1ab187c1b03246a7eb01f))
|
||||||
|
* update some argument counts in pre-allocs ([f6974eb](https://github.com/go-redis/redis/commit/f6974ebb5c40a8adf90d2cacab6dc297f4eba4c2))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add redis v7's NX, XX, GT, LT expire variants ([e19bbb2](https://github.com/go-redis/redis/commit/e19bbb26e2e395c6e077b48d80d79e99f729a8b8))
|
||||||
|
* add support for acl sentinel auth in universal client ([ab0ccc4](https://github.com/go-redis/redis/commit/ab0ccc47413f9b2a6eabc852fed5005a3ee1af6e))
|
||||||
|
* add support for COPY command ([#2016](https://github.com/go-redis/redis/issues/2016)) ([730afbc](https://github.com/go-redis/redis/commit/730afbcffb93760e8a36cc06cfe55ab102b693a7))
|
||||||
|
* add support for passing extra attributes added to spans ([39faaa1](https://github.com/go-redis/redis/commit/39faaa171523834ba527c9789710c4fde87f5a2e))
|
||||||
|
* add support for time.Duration write and scan ([2f1b74e](https://github.com/go-redis/redis/commit/2f1b74e20cdd7719b2aecf0768d3e3ae7c3e781b))
|
||||||
|
* **redisotel:** ability to override TracerProvider ([#1998](https://github.com/go-redis/redis/issues/1998)) ([bf8d4aa](https://github.com/go-redis/redis/commit/bf8d4aa60c00366cda2e98c3ddddc8cf68507417))
|
||||||
|
* set net.peer.name and net.peer.port in otel example ([69bf454](https://github.com/go-redis/redis/commit/69bf454f706204211cd34835f76b2e8192d3766d))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [8.11.4](https://github.com/go-redis/redis/compare/v8.11.3...v8.11.4) (2021-10-04)
|
## [8.11.4](https://github.com/go-redis/redis/compare/v8.11.3...v8.11.4) (2021-10-04)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
39
vendor/github.com/go-redis/redis/v8/README.md
generated
vendored
39
vendor/github.com/go-redis/redis/v8/README.md
generated
vendored
@@ -1,19 +1,16 @@
|
|||||||
<p align="center">
|
# Redis client for Go
|
||||||
<a href="https://uptrace.dev/?utm_source=gh-redis&utm_campaign=gh-redis-banner1">
|
|
||||||
<img src="https://raw.githubusercontent.com/uptrace/roadmap/master/banner1.png" alt="All-in-one tool to optimize performance and monitor errors & logs">
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
# Redis client for Golang
|
|
||||||
|
|
||||||

|

|
||||||
[](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc)
|
[](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc)
|
||||||
[](https://redis.uptrace.dev/)
|
[](https://redis.uptrace.dev/)
|
||||||
[](https://discord.gg/rWtp5Aj)
|
|
||||||
|
|
||||||
- To ask questions, join [Discord](https://discord.gg/rWtp5Aj) or use
|
go-redis is brought to you by :star: [**uptrace/uptrace**](https://github.com/uptrace/uptrace).
|
||||||
[Discussions](https://github.com/go-redis/redis/discussions).
|
Uptrace is an open source and blazingly fast **distributed tracing** backend powered by
|
||||||
- [Newsletter](https://blog.uptrace.dev/pages/newsletter.html) to get latest updates.
|
OpenTelemetry and ClickHouse. Give it a star as well!
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
- [Discussions](https://github.com/go-redis/redis/discussions)
|
||||||
- [Documentation](https://redis.uptrace.dev)
|
- [Documentation](https://redis.uptrace.dev)
|
||||||
- [Reference](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc)
|
- [Reference](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc)
|
||||||
- [Examples](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#pkg-examples)
|
- [Examples](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#pkg-examples)
|
||||||
@@ -22,15 +19,14 @@
|
|||||||
Other projects you may like:
|
Other projects you may like:
|
||||||
|
|
||||||
- [Bun](https://bun.uptrace.dev) - fast and simple SQL client for PostgreSQL, MySQL, and SQLite.
|
- [Bun](https://bun.uptrace.dev) - fast and simple SQL client for PostgreSQL, MySQL, and SQLite.
|
||||||
- [treemux](https://github.com/vmihailenco/treemux) - high-speed, flexible, tree-based HTTP router
|
- [BunRouter](https://bunrouter.uptrace.dev/) - fast and flexible HTTP router for Go.
|
||||||
for Go.
|
|
||||||
|
|
||||||
## Ecosystem
|
## Ecosystem
|
||||||
|
|
||||||
- [Redis Mock](https://github.com/go-redis/redismock).
|
- [Redis Mock](https://github.com/go-redis/redismock)
|
||||||
- [Distributed Locks](https://github.com/bsm/redislock).
|
- [Distributed Locks](https://github.com/bsm/redislock)
|
||||||
- [Redis Cache](https://github.com/go-redis/cache).
|
- [Redis Cache](https://github.com/go-redis/cache)
|
||||||
- [Rate limiting](https://github.com/go-redis/redis_rate).
|
- [Rate limiting](https://github.com/go-redis/redis_rate)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -39,16 +35,16 @@ Other projects you may like:
|
|||||||
[circuit breaker](https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern) support.
|
[circuit breaker](https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern) support.
|
||||||
- [Pub/Sub](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#PubSub).
|
- [Pub/Sub](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#PubSub).
|
||||||
- [Transactions](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-TxPipeline).
|
- [Transactions](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-TxPipeline).
|
||||||
- [Pipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-Pipeline) and
|
- [Pipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client.Pipeline) and
|
||||||
[TxPipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-TxPipeline).
|
[TxPipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client.TxPipeline).
|
||||||
- [Scripting](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Script).
|
- [Scripting](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Script).
|
||||||
- [Timeouts](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Options).
|
- [Timeouts](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Options).
|
||||||
- [Redis Sentinel](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewFailoverClient).
|
- [Redis Sentinel](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewFailoverClient).
|
||||||
- [Redis Cluster](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewClusterClient).
|
- [Redis Cluster](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewClusterClient).
|
||||||
- [Cluster of Redis Servers](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-NewClusterClient--ManualSetup)
|
- [Cluster of Redis Servers](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-NewClusterClient-ManualSetup)
|
||||||
without using cluster mode and Redis Sentinel.
|
without using cluster mode and Redis Sentinel.
|
||||||
- [Ring](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewRing).
|
- [Ring](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewRing).
|
||||||
- [Instrumentation](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#ex-package--Instrumentation).
|
- [Instrumentation](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-package-Instrumentation).
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -72,6 +68,7 @@ go get github.com/go-redis/redis/v8
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/go-redis/redis/v8"
|
"github.com/go-redis/redis/v8"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ctx = context.Background()
|
var ctx = context.Background()
|
||||||
|
|||||||
14
vendor/github.com/go-redis/redis/v8/command.go
generated
vendored
14
vendor/github.com/go-redis/redis/v8/command.go
generated
vendored
@@ -20,7 +20,7 @@ type Cmder interface {
|
|||||||
String() string
|
String() string
|
||||||
stringArg(int) string
|
stringArg(int) string
|
||||||
firstKeyPos() int8
|
firstKeyPos() int8
|
||||||
setFirstKeyPos(int8)
|
SetFirstKeyPos(int8)
|
||||||
|
|
||||||
readTimeout() *time.Duration
|
readTimeout() *time.Duration
|
||||||
readReply(rd *proto.Reader) error
|
readReply(rd *proto.Reader) error
|
||||||
@@ -151,15 +151,21 @@ func (cmd *baseCmd) stringArg(pos int) string {
|
|||||||
if pos < 0 || pos >= len(cmd.args) {
|
if pos < 0 || pos >= len(cmd.args) {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
s, _ := cmd.args[pos].(string)
|
arg := cmd.args[pos]
|
||||||
return s
|
switch v := arg.(type) {
|
||||||
|
case string:
|
||||||
|
return v
|
||||||
|
default:
|
||||||
|
// TODO: consider using appendArg
|
||||||
|
return fmt.Sprint(v)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *baseCmd) firstKeyPos() int8 {
|
func (cmd *baseCmd) firstKeyPos() int8 {
|
||||||
return cmd.keyPos
|
return cmd.keyPos
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *baseCmd) setFirstKeyPos(keyPos int8) {
|
func (cmd *baseCmd) SetFirstKeyPos(keyPos int8) {
|
||||||
cmd.keyPos = keyPos
|
cmd.keyPos = keyPos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
82
vendor/github.com/go-redis/redis/v8/commands.go
generated
vendored
82
vendor/github.com/go-redis/redis/v8/commands.go
generated
vendored
@@ -96,6 +96,10 @@ type Cmdable interface {
|
|||||||
Exists(ctx context.Context, keys ...string) *IntCmd
|
Exists(ctx context.Context, keys ...string) *IntCmd
|
||||||
Expire(ctx context.Context, key string, expiration time.Duration) *BoolCmd
|
Expire(ctx context.Context, key string, expiration time.Duration) *BoolCmd
|
||||||
ExpireAt(ctx context.Context, key string, tm time.Time) *BoolCmd
|
ExpireAt(ctx context.Context, key string, tm time.Time) *BoolCmd
|
||||||
|
ExpireNX(ctx context.Context, key string, expiration time.Duration) *BoolCmd
|
||||||
|
ExpireXX(ctx context.Context, key string, expiration time.Duration) *BoolCmd
|
||||||
|
ExpireGT(ctx context.Context, key string, expiration time.Duration) *BoolCmd
|
||||||
|
ExpireLT(ctx context.Context, key string, expiration time.Duration) *BoolCmd
|
||||||
Keys(ctx context.Context, pattern string) *StringSliceCmd
|
Keys(ctx context.Context, pattern string) *StringSliceCmd
|
||||||
Migrate(ctx context.Context, host, port, key string, db int, timeout time.Duration) *StatusCmd
|
Migrate(ctx context.Context, host, port, key string, db int, timeout time.Duration) *StatusCmd
|
||||||
Move(ctx context.Context, key string, db int) *BoolCmd
|
Move(ctx context.Context, key string, db int) *BoolCmd
|
||||||
@@ -139,6 +143,7 @@ type Cmdable interface {
|
|||||||
SetXX(ctx context.Context, key string, value interface{}, expiration time.Duration) *BoolCmd
|
SetXX(ctx context.Context, key string, value interface{}, expiration time.Duration) *BoolCmd
|
||||||
SetRange(ctx context.Context, key string, offset int64, value string) *IntCmd
|
SetRange(ctx context.Context, key string, offset int64, value string) *IntCmd
|
||||||
StrLen(ctx context.Context, key string) *IntCmd
|
StrLen(ctx context.Context, key string) *IntCmd
|
||||||
|
Copy(ctx context.Context, sourceKey string, destKey string, db int, replace bool) *IntCmd
|
||||||
|
|
||||||
GetBit(ctx context.Context, key string, offset int64) *IntCmd
|
GetBit(ctx context.Context, key string, offset int64) *IntCmd
|
||||||
SetBit(ctx context.Context, key string, offset int64, value int) *IntCmd
|
SetBit(ctx context.Context, key string, offset int64, value int) *IntCmd
|
||||||
@@ -431,6 +436,7 @@ func (c statefulCmdable) AuthACL(ctx context.Context, username, password string)
|
|||||||
|
|
||||||
func (c cmdable) Wait(ctx context.Context, numSlaves int, timeout time.Duration) *IntCmd {
|
func (c cmdable) Wait(ctx context.Context, numSlaves int, timeout time.Duration) *IntCmd {
|
||||||
cmd := NewIntCmd(ctx, "wait", numSlaves, int(timeout/time.Millisecond))
|
cmd := NewIntCmd(ctx, "wait", numSlaves, int(timeout/time.Millisecond))
|
||||||
|
cmd.setReadTimeout(timeout)
|
||||||
_ = c(ctx, cmd)
|
_ = c(ctx, cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -525,7 +531,37 @@ func (c cmdable) Exists(ctx context.Context, keys ...string) *IntCmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c cmdable) Expire(ctx context.Context, key string, expiration time.Duration) *BoolCmd {
|
func (c cmdable) Expire(ctx context.Context, key string, expiration time.Duration) *BoolCmd {
|
||||||
cmd := NewBoolCmd(ctx, "expire", key, formatSec(ctx, expiration))
|
return c.expire(ctx, key, expiration, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c cmdable) ExpireNX(ctx context.Context, key string, expiration time.Duration) *BoolCmd {
|
||||||
|
return c.expire(ctx, key, expiration, "NX")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c cmdable) ExpireXX(ctx context.Context, key string, expiration time.Duration) *BoolCmd {
|
||||||
|
return c.expire(ctx, key, expiration, "XX")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c cmdable) ExpireGT(ctx context.Context, key string, expiration time.Duration) *BoolCmd {
|
||||||
|
return c.expire(ctx, key, expiration, "GT")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c cmdable) ExpireLT(ctx context.Context, key string, expiration time.Duration) *BoolCmd {
|
||||||
|
return c.expire(ctx, key, expiration, "LT")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c cmdable) expire(
|
||||||
|
ctx context.Context, key string, expiration time.Duration, mode string,
|
||||||
|
) *BoolCmd {
|
||||||
|
args := make([]interface{}, 3, 4)
|
||||||
|
args[0] = "expire"
|
||||||
|
args[1] = key
|
||||||
|
args[2] = formatSec(ctx, expiration)
|
||||||
|
if mode != "" {
|
||||||
|
args = append(args, mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := NewBoolCmd(ctx, args...)
|
||||||
_ = c(ctx, cmd)
|
_ = c(ctx, cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -990,6 +1026,16 @@ func (c cmdable) StrLen(ctx context.Context, key string) *IntCmd {
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c cmdable) Copy(ctx context.Context, sourceKey, destKey string, db int, replace bool) *IntCmd {
|
||||||
|
args := []interface{}{"copy", sourceKey, destKey, "DB", db}
|
||||||
|
if replace {
|
||||||
|
args = append(args, "REPLACE")
|
||||||
|
}
|
||||||
|
cmd := NewIntCmd(ctx, args...)
|
||||||
|
_ = c(ctx, cmd)
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
func (c cmdable) GetBit(ctx context.Context, key string, offset int64) *IntCmd {
|
func (c cmdable) GetBit(ctx context.Context, key string, offset int64) *IntCmd {
|
||||||
@@ -1778,7 +1824,7 @@ type XReadArgs struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c cmdable) XRead(ctx context.Context, a *XReadArgs) *XStreamSliceCmd {
|
func (c cmdable) XRead(ctx context.Context, a *XReadArgs) *XStreamSliceCmd {
|
||||||
args := make([]interface{}, 0, 5+len(a.Streams))
|
args := make([]interface{}, 0, 6+len(a.Streams))
|
||||||
args = append(args, "xread")
|
args = append(args, "xread")
|
||||||
|
|
||||||
keyPos := int8(1)
|
keyPos := int8(1)
|
||||||
@@ -1802,7 +1848,7 @@ func (c cmdable) XRead(ctx context.Context, a *XReadArgs) *XStreamSliceCmd {
|
|||||||
if a.Block >= 0 {
|
if a.Block >= 0 {
|
||||||
cmd.setReadTimeout(a.Block)
|
cmd.setReadTimeout(a.Block)
|
||||||
}
|
}
|
||||||
cmd.setFirstKeyPos(keyPos)
|
cmd.SetFirstKeyPos(keyPos)
|
||||||
_ = c(ctx, cmd)
|
_ = c(ctx, cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -1860,7 +1906,7 @@ type XReadGroupArgs struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c cmdable) XReadGroup(ctx context.Context, a *XReadGroupArgs) *XStreamSliceCmd {
|
func (c cmdable) XReadGroup(ctx context.Context, a *XReadGroupArgs) *XStreamSliceCmd {
|
||||||
args := make([]interface{}, 0, 8+len(a.Streams))
|
args := make([]interface{}, 0, 10+len(a.Streams))
|
||||||
args = append(args, "xreadgroup", "group", a.Group, a.Consumer)
|
args = append(args, "xreadgroup", "group", a.Group, a.Consumer)
|
||||||
|
|
||||||
keyPos := int8(4)
|
keyPos := int8(4)
|
||||||
@@ -1886,7 +1932,7 @@ func (c cmdable) XReadGroup(ctx context.Context, a *XReadGroupArgs) *XStreamSlic
|
|||||||
if a.Block >= 0 {
|
if a.Block >= 0 {
|
||||||
cmd.setReadTimeout(a.Block)
|
cmd.setReadTimeout(a.Block)
|
||||||
}
|
}
|
||||||
cmd.setFirstKeyPos(keyPos)
|
cmd.SetFirstKeyPos(keyPos)
|
||||||
_ = c(ctx, cmd)
|
_ = c(ctx, cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -1957,7 +2003,7 @@ func (c cmdable) XAutoClaimJustID(ctx context.Context, a *XAutoClaimArgs) *XAuto
|
|||||||
}
|
}
|
||||||
|
|
||||||
func xAutoClaimArgs(ctx context.Context, a *XAutoClaimArgs) []interface{} {
|
func xAutoClaimArgs(ctx context.Context, a *XAutoClaimArgs) []interface{} {
|
||||||
args := make([]interface{}, 0, 9)
|
args := make([]interface{}, 0, 8)
|
||||||
args = append(args, "xautoclaim", a.Stream, a.Group, a.Consumer, formatMs(ctx, a.MinIdle), a.Start)
|
args = append(args, "xautoclaim", a.Stream, a.Group, a.Consumer, formatMs(ctx, a.MinIdle), a.Start)
|
||||||
if a.Count > 0 {
|
if a.Count > 0 {
|
||||||
args = append(args, "count", a.Count)
|
args = append(args, "count", a.Count)
|
||||||
@@ -1989,7 +2035,7 @@ func (c cmdable) XClaimJustID(ctx context.Context, a *XClaimArgs) *StringSliceCm
|
|||||||
}
|
}
|
||||||
|
|
||||||
func xClaimArgs(a *XClaimArgs) []interface{} {
|
func xClaimArgs(a *XClaimArgs) []interface{} {
|
||||||
args := make([]interface{}, 0, 4+len(a.Messages))
|
args := make([]interface{}, 0, 5+len(a.Messages))
|
||||||
args = append(args,
|
args = append(args,
|
||||||
"xclaim",
|
"xclaim",
|
||||||
a.Stream,
|
a.Stream,
|
||||||
@@ -2362,7 +2408,7 @@ func (c cmdable) ZInterStore(ctx context.Context, destination string, store *ZSt
|
|||||||
args = append(args, "zinterstore", destination, len(store.Keys))
|
args = append(args, "zinterstore", destination, len(store.Keys))
|
||||||
args = store.appendArgs(args)
|
args = store.appendArgs(args)
|
||||||
cmd := NewIntCmd(ctx, args...)
|
cmd := NewIntCmd(ctx, args...)
|
||||||
cmd.setFirstKeyPos(3)
|
cmd.SetFirstKeyPos(3)
|
||||||
_ = c(ctx, cmd)
|
_ = c(ctx, cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -2372,7 +2418,7 @@ func (c cmdable) ZInter(ctx context.Context, store *ZStore) *StringSliceCmd {
|
|||||||
args = append(args, "zinter", len(store.Keys))
|
args = append(args, "zinter", len(store.Keys))
|
||||||
args = store.appendArgs(args)
|
args = store.appendArgs(args)
|
||||||
cmd := NewStringSliceCmd(ctx, args...)
|
cmd := NewStringSliceCmd(ctx, args...)
|
||||||
cmd.setFirstKeyPos(2)
|
cmd.SetFirstKeyPos(2)
|
||||||
_ = c(ctx, cmd)
|
_ = c(ctx, cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -2383,7 +2429,7 @@ func (c cmdable) ZInterWithScores(ctx context.Context, store *ZStore) *ZSliceCmd
|
|||||||
args = store.appendArgs(args)
|
args = store.appendArgs(args)
|
||||||
args = append(args, "withscores")
|
args = append(args, "withscores")
|
||||||
cmd := NewZSliceCmd(ctx, args...)
|
cmd := NewZSliceCmd(ctx, args...)
|
||||||
cmd.setFirstKeyPos(2)
|
cmd.SetFirstKeyPos(2)
|
||||||
_ = c(ctx, cmd)
|
_ = c(ctx, cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -2710,7 +2756,7 @@ func (c cmdable) ZUnion(ctx context.Context, store ZStore) *StringSliceCmd {
|
|||||||
args = append(args, "zunion", len(store.Keys))
|
args = append(args, "zunion", len(store.Keys))
|
||||||
args = store.appendArgs(args)
|
args = store.appendArgs(args)
|
||||||
cmd := NewStringSliceCmd(ctx, args...)
|
cmd := NewStringSliceCmd(ctx, args...)
|
||||||
cmd.setFirstKeyPos(2)
|
cmd.SetFirstKeyPos(2)
|
||||||
_ = c(ctx, cmd)
|
_ = c(ctx, cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -2721,7 +2767,7 @@ func (c cmdable) ZUnionWithScores(ctx context.Context, store ZStore) *ZSliceCmd
|
|||||||
args = store.appendArgs(args)
|
args = store.appendArgs(args)
|
||||||
args = append(args, "withscores")
|
args = append(args, "withscores")
|
||||||
cmd := NewZSliceCmd(ctx, args...)
|
cmd := NewZSliceCmd(ctx, args...)
|
||||||
cmd.setFirstKeyPos(2)
|
cmd.SetFirstKeyPos(2)
|
||||||
_ = c(ctx, cmd)
|
_ = c(ctx, cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -2731,7 +2777,7 @@ func (c cmdable) ZUnionStore(ctx context.Context, dest string, store *ZStore) *I
|
|||||||
args = append(args, "zunionstore", dest, len(store.Keys))
|
args = append(args, "zunionstore", dest, len(store.Keys))
|
||||||
args = store.appendArgs(args)
|
args = store.appendArgs(args)
|
||||||
cmd := NewIntCmd(ctx, args...)
|
cmd := NewIntCmd(ctx, args...)
|
||||||
cmd.setFirstKeyPos(3)
|
cmd.SetFirstKeyPos(3)
|
||||||
_ = c(ctx, cmd)
|
_ = c(ctx, cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -2761,7 +2807,7 @@ func (c cmdable) ZDiff(ctx context.Context, keys ...string) *StringSliceCmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd := NewStringSliceCmd(ctx, args...)
|
cmd := NewStringSliceCmd(ctx, args...)
|
||||||
cmd.setFirstKeyPos(2)
|
cmd.SetFirstKeyPos(2)
|
||||||
_ = c(ctx, cmd)
|
_ = c(ctx, cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -2777,7 +2823,7 @@ func (c cmdable) ZDiffWithScores(ctx context.Context, keys ...string) *ZSliceCmd
|
|||||||
args[len(keys)+2] = "withscores"
|
args[len(keys)+2] = "withscores"
|
||||||
|
|
||||||
cmd := NewZSliceCmd(ctx, args...)
|
cmd := NewZSliceCmd(ctx, args...)
|
||||||
cmd.setFirstKeyPos(2)
|
cmd.SetFirstKeyPos(2)
|
||||||
_ = c(ctx, cmd)
|
_ = c(ctx, cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -3053,7 +3099,7 @@ func (c cmdable) MemoryUsage(ctx context.Context, key string, samples ...int) *I
|
|||||||
args = append(args, "SAMPLES", samples[0])
|
args = append(args, "SAMPLES", samples[0])
|
||||||
}
|
}
|
||||||
cmd := NewIntCmd(ctx, args...)
|
cmd := NewIntCmd(ctx, args...)
|
||||||
cmd.setFirstKeyPos(2)
|
cmd.SetFirstKeyPos(2)
|
||||||
_ = c(ctx, cmd)
|
_ = c(ctx, cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -3070,7 +3116,7 @@ func (c cmdable) Eval(ctx context.Context, script string, keys []string, args ..
|
|||||||
}
|
}
|
||||||
cmdArgs = appendArgs(cmdArgs, args)
|
cmdArgs = appendArgs(cmdArgs, args)
|
||||||
cmd := NewCmd(ctx, cmdArgs...)
|
cmd := NewCmd(ctx, cmdArgs...)
|
||||||
cmd.setFirstKeyPos(3)
|
cmd.SetFirstKeyPos(3)
|
||||||
_ = c(ctx, cmd)
|
_ = c(ctx, cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -3085,7 +3131,7 @@ func (c cmdable) EvalSha(ctx context.Context, sha1 string, keys []string, args .
|
|||||||
}
|
}
|
||||||
cmdArgs = appendArgs(cmdArgs, args)
|
cmdArgs = appendArgs(cmdArgs, args)
|
||||||
cmd := NewCmd(ctx, cmdArgs...)
|
cmd := NewCmd(ctx, cmdArgs...)
|
||||||
cmd.setFirstKeyPos(3)
|
cmd.SetFirstKeyPos(3)
|
||||||
_ = c(ctx, cmd)
|
_ = c(ctx, cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
2
vendor/github.com/go-redis/redis/v8/error.go
generated
vendored
2
vendor/github.com/go-redis/redis/v8/error.go
generated
vendored
@@ -134,7 +134,7 @@ func isMovedSameConnAddr(err error, addr string) bool {
|
|||||||
if !strings.HasPrefix(redisError, "MOVED ") {
|
if !strings.HasPrefix(redisError, "MOVED ") {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return strings.HasSuffix(redisError, addr)
|
return strings.HasSuffix(redisError, " "+addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
8
vendor/github.com/go-redis/redis/v8/internal/proto/scan.go
generated
vendored
8
vendor/github.com/go-redis/redis/v8/internal/proto/scan.go
generated
vendored
@@ -10,6 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Scan parses bytes `b` to `v` with appropriate type.
|
// Scan parses bytes `b` to `v` with appropriate type.
|
||||||
|
//nolint:gocyclo
|
||||||
func Scan(b []byte, v interface{}) error {
|
func Scan(b []byte, v interface{}) error {
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
case nil:
|
case nil:
|
||||||
@@ -105,6 +106,13 @@ func Scan(b []byte, v interface{}) error {
|
|||||||
var err error
|
var err error
|
||||||
*v, err = time.Parse(time.RFC3339Nano, util.BytesToString(b))
|
*v, err = time.Parse(time.RFC3339Nano, util.BytesToString(b))
|
||||||
return err
|
return err
|
||||||
|
case *time.Duration:
|
||||||
|
n, err := util.ParseInt(b, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*v = time.Duration(n)
|
||||||
|
return nil
|
||||||
case encoding.BinaryUnmarshaler:
|
case encoding.BinaryUnmarshaler:
|
||||||
return v.UnmarshalBinary(b)
|
return v.UnmarshalBinary(b)
|
||||||
default:
|
default:
|
||||||
|
|||||||
2
vendor/github.com/go-redis/redis/v8/internal/proto/writer.go
generated
vendored
2
vendor/github.com/go-redis/redis/v8/internal/proto/writer.go
generated
vendored
@@ -98,6 +98,8 @@ func (w *Writer) WriteArg(v interface{}) error {
|
|||||||
case time.Time:
|
case time.Time:
|
||||||
w.numBuf = v.AppendFormat(w.numBuf[:0], time.RFC3339Nano)
|
w.numBuf = v.AppendFormat(w.numBuf[:0], time.RFC3339Nano)
|
||||||
return w.bytes(w.numBuf)
|
return w.bytes(w.numBuf)
|
||||||
|
case time.Duration:
|
||||||
|
return w.int(v.Nanoseconds())
|
||||||
case encoding.BinaryMarshaler:
|
case encoding.BinaryMarshaler:
|
||||||
b, err := v.MarshalBinary()
|
b, err := v.MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
2
vendor/github.com/go-redis/redis/v8/package.json
generated
vendored
2
vendor/github.com/go-redis/redis/v8/package.json
generated
vendored
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "redis",
|
"name": "redis",
|
||||||
"version": "8.11.4",
|
"version": "8.11.5",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"repository": "git@github.com:go-redis/redis.git",
|
"repository": "git@github.com:go-redis/redis.git",
|
||||||
"author": "Vladimir Mihailenco <vladimir.webdev@gmail.com>",
|
"author": "Vladimir Mihailenco <vladimir.webdev@gmail.com>",
|
||||||
|
|||||||
10
vendor/github.com/go-redis/redis/v8/pipeline.go
generated
vendored
10
vendor/github.com/go-redis/redis/v8/pipeline.go
generated
vendored
@@ -24,6 +24,7 @@ type pipelineExecer func(context.Context, []Cmder) error
|
|||||||
// depends of your batch size and/or use TxPipeline.
|
// depends of your batch size and/or use TxPipeline.
|
||||||
type Pipeliner interface {
|
type Pipeliner interface {
|
||||||
StatefulCmdable
|
StatefulCmdable
|
||||||
|
Len() int
|
||||||
Do(ctx context.Context, args ...interface{}) *Cmd
|
Do(ctx context.Context, args ...interface{}) *Cmd
|
||||||
Process(ctx context.Context, cmd Cmder) error
|
Process(ctx context.Context, cmd Cmder) error
|
||||||
Close() error
|
Close() error
|
||||||
@@ -53,6 +54,15 @@ func (c *Pipeline) init() {
|
|||||||
c.statefulCmdable = c.Process
|
c.statefulCmdable = c.Process
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Len returns the number of queued commands.
|
||||||
|
func (c *Pipeline) Len() int {
|
||||||
|
c.mu.Lock()
|
||||||
|
ln := len(c.cmds)
|
||||||
|
c.mu.Unlock()
|
||||||
|
return ln
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do queues the custom command for later execution.
|
||||||
func (c *Pipeline) Do(ctx context.Context, args ...interface{}) *Cmd {
|
func (c *Pipeline) Do(ctx context.Context, args ...interface{}) *Cmd {
|
||||||
cmd := NewCmd(ctx, args...)
|
cmd := NewCmd(ctx, args...)
|
||||||
_ = c.Process(ctx, cmd)
|
_ = c.Process(ctx, cmd)
|
||||||
|
|||||||
2
vendor/github.com/go-redis/redis/v8/ring.go
generated
vendored
2
vendor/github.com/go-redis/redis/v8/ring.go
generated
vendored
@@ -576,7 +576,7 @@ func (c *Ring) cmdInfo(ctx context.Context, name string) *CommandInfo {
|
|||||||
}
|
}
|
||||||
info := cmdsInfo[name]
|
info := cmdsInfo[name]
|
||||||
if info == nil {
|
if info == nil {
|
||||||
internal.Logger.Printf(c.Context(), "info for cmd=%s not found", name)
|
internal.Logger.Printf(ctx, "info for cmd=%s not found", name)
|
||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|||||||
2
vendor/github.com/go-redis/redis/v8/universal.go
generated
vendored
2
vendor/github.com/go-redis/redis/v8/universal.go
generated
vendored
@@ -25,6 +25,7 @@ type UniversalOptions struct {
|
|||||||
|
|
||||||
Username string
|
Username string
|
||||||
Password string
|
Password string
|
||||||
|
SentinelUsername string
|
||||||
SentinelPassword string
|
SentinelPassword string
|
||||||
|
|
||||||
MaxRetries int
|
MaxRetries int
|
||||||
@@ -114,6 +115,7 @@ func (o *UniversalOptions) Failover() *FailoverOptions {
|
|||||||
DB: o.DB,
|
DB: o.DB,
|
||||||
Username: o.Username,
|
Username: o.Username,
|
||||||
Password: o.Password,
|
Password: o.Password,
|
||||||
|
SentinelUsername: o.SentinelUsername,
|
||||||
SentinelPassword: o.SentinelPassword,
|
SentinelPassword: o.SentinelPassword,
|
||||||
|
|
||||||
MaxRetries: o.MaxRetries,
|
MaxRetries: o.MaxRetries,
|
||||||
|
|||||||
2
vendor/github.com/go-redis/redis/v8/version.go
generated
vendored
2
vendor/github.com/go-redis/redis/v8/version.go
generated
vendored
@@ -2,5 +2,5 @@ package redis
|
|||||||
|
|
||||||
// Version is the current release version.
|
// Version is the current release version.
|
||||||
func Version() string {
|
func Version() string {
|
||||||
return "8.11.4"
|
return "8.11.5"
|
||||||
}
|
}
|
||||||
|
|||||||
48
vendor/github.com/hjson/hjson-go/.travis.yml
generated
vendored
48
vendor/github.com/hjson/hjson-go/.travis.yml
generated
vendored
@@ -1,48 +0,0 @@
|
|||||||
language: go
|
|
||||||
go:
|
|
||||||
- 1.6
|
|
||||||
- 1.7
|
|
||||||
- 1.8
|
|
||||||
- tip
|
|
||||||
install: true
|
|
||||||
script:
|
|
||||||
- go install github.com/hjson/hjson-go
|
|
||||||
- go install github.com/hjson/hjson-go/hjson-cli
|
|
||||||
- go test -v github.com/hjson/hjson-go
|
|
||||||
before_deploy:
|
|
||||||
- ./build_release.sh
|
|
||||||
deploy:
|
|
||||||
provider: releases
|
|
||||||
file:
|
|
||||||
- _dist/darwin_386.tar.gz
|
|
||||||
- _dist/darwin_amd64.tar.gz
|
|
||||||
- _dist/dragonfly_amd64.tar.gz
|
|
||||||
- _dist/freebsd_386.tar.gz
|
|
||||||
- _dist/freebsd_amd64.tar.gz
|
|
||||||
- _dist/freebsd_arm.tar.gz
|
|
||||||
- _dist/linux_386.tar.gz
|
|
||||||
- _dist/linux_amd64.tar.gz
|
|
||||||
- _dist/linux_arm.tar.gz
|
|
||||||
- _dist/linux_arm64.tar.gz
|
|
||||||
- _dist/linux_mips64.tar.gz
|
|
||||||
- _dist/linux_mips64le.tar.gz
|
|
||||||
- _dist/linux_ppc64.tar.gz
|
|
||||||
- _dist/linux_ppc64le.tar.gz
|
|
||||||
- _dist/netbsd_386.tar.gz
|
|
||||||
- _dist/netbsd_amd64.tar.gz
|
|
||||||
- _dist/netbsd_arm.tar.gz
|
|
||||||
- _dist/openbsd_386.tar.gz
|
|
||||||
- _dist/openbsd_amd64.tar.gz
|
|
||||||
- _dist/openbsd_arm.tar.gz
|
|
||||||
- _dist/plan9_386.tar.gz
|
|
||||||
- _dist/plan9_amd64.tar.gz
|
|
||||||
- _dist/solaris_amd64.tar.gz
|
|
||||||
- _dist/windows_386.zip
|
|
||||||
- _dist/windows_amd64.zip
|
|
||||||
overwrite: true
|
|
||||||
skip_cleanup: true
|
|
||||||
on:
|
|
||||||
tags: true
|
|
||||||
go: 1.7
|
|
||||||
api-key:
|
|
||||||
secure: RAnrBG7xantKdUBlIsv8Od9yZ0GTwCsJ7d1V+hSEC3JSz76+Ie4v1nJw+rD0Rp25zxDAM2qSkMfIaQJVSQ5tYg3N8C/d+/lfeRNBwLhHEsQztsaE5BU0I/qrkKq0pGMoG+cu6ZJ06xEgECPKOamwQ2wSY0IiIwVn0eNN/ufMsZUTmPgBE4+lx9eEWYDqMxy4tfgLMC/ry2fnA3zc4fQk0TboodLkI0SgwMq7cHcm95j9kHWpydbwr8IhQ6pucLM9YuKGv2fNHywlQ6Z9rhpYdiK/9KUofW20Rm4OB1MBHLLhLdQ0qCkVPswhGRdFPcBcN7lvv8Czcp3Hl4LQ4UzxOXf58mEWbh4r6VbUjZgRnpMy8Ms9CcyLjwaRbJPKA/kI53yjeEViFbDlOtBV8qdVqx5orCUrpU2ML/iEltVDL7pukhjuKd0K/2c3s8gJwH4LaGEfQjj2DvYkQgK0XsWSOXhYF4LaN0qhiQ3xiss1bhjJIIIhD3PHPy+dCsazKoJtNRHoUyP9RYz8EjcwI7BsaEEzskaXuUSvLz3+k6f6DZvPydUDXDGYqX0H2dXCT5H0IaCrSAkDVcGageXt4vkzKb45/el1W5VME/q/WpGAIPfsJ2beR7ALlm1RhXdWTJpwq6LM/YbYy/6U/HlqQCwB4x/nwKXy1ToDukCrHy57yGU=
|
|
||||||
2
vendor/github.com/hjson/hjson-go/README.md
generated
vendored
2
vendor/github.com/hjson/hjson-go/README.md
generated
vendored
@@ -1,6 +1,6 @@
|
|||||||
# hjson-go
|
# hjson-go
|
||||||
|
|
||||||
[](https://travis-ci.org/hjson/hjson-go)
|
[](https://github.com/hjson/hjson-go/actions)
|
||||||
[](https://github.com/hjson/hjson-go/releases)
|
[](https://github.com/hjson/hjson-go/releases)
|
||||||
[](https://goreportcard.com/report/github.com/hjson/hjson-go)
|
[](https://goreportcard.com/report/github.com/hjson/hjson-go)
|
||||||
[](http://gocover.io/github.com/hjson/hjson-go/)
|
[](http://gocover.io/github.com/hjson/hjson-go/)
|
||||||
|
|||||||
76
vendor/github.com/hjson/hjson-go/encode.go
generated
vendored
76
vendor/github.com/hjson/hjson-go/encode.go
generated
vendored
@@ -20,12 +20,16 @@ type EncoderOptions struct {
|
|||||||
Eol string
|
Eol string
|
||||||
// Place braces on the same line
|
// Place braces on the same line
|
||||||
BracesSameLine bool
|
BracesSameLine bool
|
||||||
// Deprecated: Hjson always emits braces
|
// Emit braces for the root object
|
||||||
EmitRootBraces bool
|
EmitRootBraces bool
|
||||||
// Always place string in quotes
|
// Always place string in quotes
|
||||||
QuoteAlways bool
|
QuoteAlways bool
|
||||||
|
// Place string in quotes if it could otherwise be a number, boolean or null
|
||||||
|
QuoteAmbiguousStrings bool
|
||||||
// Indent string
|
// Indent string
|
||||||
IndentBy string
|
IndentBy string
|
||||||
|
// Base indentation string
|
||||||
|
BaseIndentation string
|
||||||
// Allow the -0 value (unlike ES6)
|
// Allow the -0 value (unlike ES6)
|
||||||
AllowMinusZero bool
|
AllowMinusZero bool
|
||||||
// Encode unknown values as 'null'
|
// Encode unknown values as 'null'
|
||||||
@@ -39,7 +43,9 @@ func DefaultOptions() EncoderOptions {
|
|||||||
opt.BracesSameLine = false
|
opt.BracesSameLine = false
|
||||||
opt.EmitRootBraces = true
|
opt.EmitRootBraces = true
|
||||||
opt.QuoteAlways = false
|
opt.QuoteAlways = false
|
||||||
|
opt.QuoteAmbiguousStrings = true
|
||||||
opt.IndentBy = " "
|
opt.IndentBy = " "
|
||||||
|
opt.BaseIndentation = ""
|
||||||
opt.AllowMinusZero = false
|
opt.AllowMinusZero = false
|
||||||
opt.UnknownAsNull = false
|
opt.UnknownAsNull = false
|
||||||
return opt
|
return opt
|
||||||
@@ -97,9 +103,8 @@ func (e *hjsonEncoder) quote(value string, separator string, isRootObject bool)
|
|||||||
if len(value) == 0 {
|
if len(value) == 0 {
|
||||||
e.WriteString(separator + `""`)
|
e.WriteString(separator + `""`)
|
||||||
} else if e.QuoteAlways ||
|
} else if e.QuoteAlways ||
|
||||||
needsQuotes.MatchString(value) ||
|
needsQuotes.MatchString(value) || (e.QuoteAmbiguousStrings && (startsWithNumber([]byte(value)) ||
|
||||||
startsWithNumber([]byte(value)) ||
|
startsWithKeyword.MatchString(value))) {
|
||||||
startsWithKeyword.MatchString(value) {
|
|
||||||
|
|
||||||
// If the string contains no control characters, no quote characters, and no
|
// If the string contains no control characters, no quote characters, and no
|
||||||
// backslash characters, then we can safely slap some quotes around it.
|
// backslash characters, then we can safely slap some quotes around it.
|
||||||
@@ -178,6 +183,7 @@ func (s sortAlpha) Less(i, j int) bool {
|
|||||||
|
|
||||||
func (e *hjsonEncoder) writeIndent(indent int) {
|
func (e *hjsonEncoder) writeIndent(indent int) {
|
||||||
e.WriteString(e.Eol)
|
e.WriteString(e.Eol)
|
||||||
|
e.WriteString(e.BaseIndentation)
|
||||||
for i := 0; i < indent; i++ {
|
for i := 0; i < indent; i++ {
|
||||||
e.WriteString(e.IndentBy)
|
e.WriteString(e.IndentBy)
|
||||||
}
|
}
|
||||||
@@ -207,8 +213,7 @@ func (e *hjsonEncoder) str(value reflect.Value, noIndent bool, separator string,
|
|||||||
e.WriteString("null")
|
e.WriteString("null")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
value = value.Elem()
|
return e.str(value.Elem(),noIndent,separator,isRootObject)
|
||||||
kind = value.Kind()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if value.Type().Implements(marshaler) {
|
if value.Type().Implements(marshaler) {
|
||||||
@@ -296,20 +301,25 @@ func (e *hjsonEncoder) str(value reflect.Value, noIndent bool, separator string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
indent1 := e.indent
|
indent1 := e.indent
|
||||||
e.indent++
|
if !isRootObject || e.EmitRootBraces {
|
||||||
if !noIndent && !e.BracesSameLine {
|
if !noIndent && !e.BracesSameLine {
|
||||||
e.writeIndent(indent1)
|
e.writeIndent(e.indent)
|
||||||
} else {
|
} else {
|
||||||
e.WriteString(separator)
|
e.WriteString(separator)
|
||||||
|
}
|
||||||
|
|
||||||
|
e.indent++
|
||||||
|
e.WriteString("{")
|
||||||
}
|
}
|
||||||
e.WriteString("{")
|
|
||||||
|
|
||||||
keys := value.MapKeys()
|
keys := value.MapKeys()
|
||||||
sort.Sort(sortAlpha(keys))
|
sort.Sort(sortAlpha(keys))
|
||||||
|
|
||||||
// Join all of the member texts together, separated with newlines
|
// Join all of the member texts together, separated with newlines
|
||||||
for i := 0; i < len; i++ {
|
for i := 0; i < len; i++ {
|
||||||
e.writeIndent(e.indent)
|
if i > 0 || !isRootObject || e.EmitRootBraces {
|
||||||
|
e.writeIndent(e.indent)
|
||||||
|
}
|
||||||
e.WriteString(e.quoteName(keys[i].String()))
|
e.WriteString(e.quoteName(keys[i].String()))
|
||||||
e.WriteString(":")
|
e.WriteString(":")
|
||||||
if err := e.str(value.MapIndex(keys[i]), false, " ", false); err != nil {
|
if err := e.str(value.MapIndex(keys[i]), false, " ", false); err != nil {
|
||||||
@@ -317,8 +327,10 @@ func (e *hjsonEncoder) str(value reflect.Value, noIndent bool, separator string,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e.writeIndent(indent1)
|
if !isRootObject || e.EmitRootBraces {
|
||||||
e.WriteString("}")
|
e.writeIndent(indent1)
|
||||||
|
e.WriteString("}")
|
||||||
|
}
|
||||||
e.indent = indent1
|
e.indent = indent1
|
||||||
|
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
@@ -331,13 +343,16 @@ func (e *hjsonEncoder) str(value reflect.Value, noIndent bool, separator string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
indent1 := e.indent
|
indent1 := e.indent
|
||||||
e.indent++
|
if !isRootObject || e.EmitRootBraces {
|
||||||
if !noIndent && !e.BracesSameLine {
|
if !noIndent && !e.BracesSameLine {
|
||||||
e.writeIndent(indent1)
|
e.writeIndent(e.indent)
|
||||||
} else {
|
} else {
|
||||||
e.WriteString(separator)
|
e.WriteString(separator)
|
||||||
|
}
|
||||||
|
|
||||||
|
e.indent++
|
||||||
|
e.WriteString("{")
|
||||||
}
|
}
|
||||||
e.WriteString("{")
|
|
||||||
|
|
||||||
// Join all of the member texts together, separated with newlines
|
// Join all of the member texts together, separated with newlines
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
@@ -367,11 +382,15 @@ func (e *hjsonEncoder) str(value reflect.Value, noIndent bool, separator string,
|
|||||||
}
|
}
|
||||||
if len(jsonComment) > 0 {
|
if len(jsonComment) > 0 {
|
||||||
for _, line := range strings.Split(jsonComment, e.Eol) {
|
for _, line := range strings.Split(jsonComment, e.Eol) {
|
||||||
e.writeIndent(e.indent)
|
if i > 0 || !isRootObject || e.EmitRootBraces {
|
||||||
|
e.writeIndent(e.indent)
|
||||||
|
}
|
||||||
e.WriteString(fmt.Sprintf("# %s", line))
|
e.WriteString(fmt.Sprintf("# %s", line))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.writeIndent(e.indent)
|
if i > 0 || !isRootObject || e.EmitRootBraces {
|
||||||
|
e.writeIndent(e.indent)
|
||||||
|
}
|
||||||
e.WriteString(e.quoteName(name))
|
e.WriteString(e.quoteName(name))
|
||||||
e.WriteString(":")
|
e.WriteString(":")
|
||||||
if err := e.str(curField, false, " ", false); err != nil {
|
if err := e.str(curField, false, " ", false); err != nil {
|
||||||
@@ -382,8 +401,10 @@ func (e *hjsonEncoder) str(value reflect.Value, noIndent bool, separator string,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e.writeIndent(indent1)
|
if !isRootObject || e.EmitRootBraces {
|
||||||
e.WriteString("}")
|
e.writeIndent(indent1)
|
||||||
|
e.WriteString("}")
|
||||||
|
}
|
||||||
|
|
||||||
e.indent = indent1
|
e.indent = indent1
|
||||||
|
|
||||||
@@ -457,10 +478,13 @@ func MarshalWithOptions(v interface{}, options EncoderOptions) ([]byte, error) {
|
|||||||
e.indent = 0
|
e.indent = 0
|
||||||
e.Eol = options.Eol
|
e.Eol = options.Eol
|
||||||
e.BracesSameLine = options.BracesSameLine
|
e.BracesSameLine = options.BracesSameLine
|
||||||
|
e.EmitRootBraces = options.EmitRootBraces
|
||||||
e.QuoteAlways = options.QuoteAlways
|
e.QuoteAlways = options.QuoteAlways
|
||||||
|
e.QuoteAmbiguousStrings = options.QuoteAmbiguousStrings
|
||||||
e.IndentBy = options.IndentBy
|
e.IndentBy = options.IndentBy
|
||||||
|
e.BaseIndentation = options.BaseIndentation
|
||||||
|
|
||||||
err := e.str(reflect.ValueOf(v), true, "", true)
|
err := e.str(reflect.ValueOf(v), true, e.BaseIndentation, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
4
vendor/github.com/sirupsen/logrus/.gitignore
generated
vendored
4
vendor/github.com/sirupsen/logrus/.gitignore
generated
vendored
@@ -1,4 +0,0 @@
|
|||||||
logrus
|
|
||||||
vendor
|
|
||||||
|
|
||||||
.idea/
|
|
||||||
40
vendor/github.com/sirupsen/logrus/.golangci.yml
generated
vendored
40
vendor/github.com/sirupsen/logrus/.golangci.yml
generated
vendored
@@ -1,40 +0,0 @@
|
|||||||
run:
|
|
||||||
# do not run on test files yet
|
|
||||||
tests: false
|
|
||||||
|
|
||||||
# all available settings of specific linters
|
|
||||||
linters-settings:
|
|
||||||
errcheck:
|
|
||||||
# report about not checking of errors in type assetions: `a := b.(MyStruct)`;
|
|
||||||
# default is false: such cases aren't reported by default.
|
|
||||||
check-type-assertions: false
|
|
||||||
|
|
||||||
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
|
|
||||||
# default is false: such cases aren't reported by default.
|
|
||||||
check-blank: false
|
|
||||||
|
|
||||||
lll:
|
|
||||||
line-length: 100
|
|
||||||
tab-width: 4
|
|
||||||
|
|
||||||
prealloc:
|
|
||||||
simple: false
|
|
||||||
range-loops: false
|
|
||||||
for-loops: false
|
|
||||||
|
|
||||||
whitespace:
|
|
||||||
multi-if: false # Enforces newlines (or comments) after every multi-line if statement
|
|
||||||
multi-func: false # Enforces newlines (or comments) after every multi-line function signature
|
|
||||||
|
|
||||||
linters:
|
|
||||||
enable:
|
|
||||||
- megacheck
|
|
||||||
- govet
|
|
||||||
disable:
|
|
||||||
- maligned
|
|
||||||
- prealloc
|
|
||||||
disable-all: false
|
|
||||||
presets:
|
|
||||||
- bugs
|
|
||||||
- unused
|
|
||||||
fast: false
|
|
||||||
15
vendor/github.com/sirupsen/logrus/.travis.yml
generated
vendored
15
vendor/github.com/sirupsen/logrus/.travis.yml
generated
vendored
@@ -1,15 +0,0 @@
|
|||||||
language: go
|
|
||||||
go_import_path: github.com/sirupsen/logrus
|
|
||||||
git:
|
|
||||||
depth: 1
|
|
||||||
env:
|
|
||||||
- GO111MODULE=on
|
|
||||||
go: 1.15.x
|
|
||||||
os: linux
|
|
||||||
install:
|
|
||||||
- ./travis/install.sh
|
|
||||||
script:
|
|
||||||
- cd ci
|
|
||||||
- go run mage.go -v -w ../ crossBuild
|
|
||||||
- go run mage.go -v -w ../ lint
|
|
||||||
- go run mage.go -v -w ../ test
|
|
||||||
259
vendor/github.com/sirupsen/logrus/CHANGELOG.md
generated
vendored
259
vendor/github.com/sirupsen/logrus/CHANGELOG.md
generated
vendored
@@ -1,259 +0,0 @@
|
|||||||
# 1.8.1
|
|
||||||
Code quality:
|
|
||||||
* move magefile in its own subdir/submodule to remove magefile dependency on logrus consumer
|
|
||||||
* improve timestamp format documentation
|
|
||||||
|
|
||||||
Fixes:
|
|
||||||
* fix race condition on logger hooks
|
|
||||||
|
|
||||||
|
|
||||||
# 1.8.0
|
|
||||||
|
|
||||||
Correct versioning number replacing v1.7.1.
|
|
||||||
|
|
||||||
# 1.7.1
|
|
||||||
|
|
||||||
Beware this release has introduced a new public API and its semver is therefore incorrect.
|
|
||||||
|
|
||||||
Code quality:
|
|
||||||
* use go 1.15 in travis
|
|
||||||
* use magefile as task runner
|
|
||||||
|
|
||||||
Fixes:
|
|
||||||
* small fixes about new go 1.13 error formatting system
|
|
||||||
* Fix for long time race condiction with mutating data hooks
|
|
||||||
|
|
||||||
Features:
|
|
||||||
* build support for zos
|
|
||||||
|
|
||||||
# 1.7.0
|
|
||||||
Fixes:
|
|
||||||
* the dependency toward a windows terminal library has been removed
|
|
||||||
|
|
||||||
Features:
|
|
||||||
* a new buffer pool management API has been added
|
|
||||||
* a set of `<LogLevel>Fn()` functions have been added
|
|
||||||
|
|
||||||
# 1.6.0
|
|
||||||
Fixes:
|
|
||||||
* end of line cleanup
|
|
||||||
* revert the entry concurrency bug fix whic leads to deadlock under some circumstances
|
|
||||||
* update dependency on go-windows-terminal-sequences to fix a crash with go 1.14
|
|
||||||
|
|
||||||
Features:
|
|
||||||
* add an option to the `TextFormatter` to completely disable fields quoting
|
|
||||||
|
|
||||||
# 1.5.0
|
|
||||||
Code quality:
|
|
||||||
* add golangci linter run on travis
|
|
||||||
|
|
||||||
Fixes:
|
|
||||||
* add mutex for hooks concurrent access on `Entry` data
|
|
||||||
* caller function field for go1.14
|
|
||||||
* fix build issue for gopherjs target
|
|
||||||
|
|
||||||
Feature:
|
|
||||||
* add an hooks/writer sub-package whose goal is to split output on different stream depending on the trace level
|
|
||||||
* add a `DisableHTMLEscape` option in the `JSONFormatter`
|
|
||||||
* add `ForceQuote` and `PadLevelText` options in the `TextFormatter`
|
|
||||||
|
|
||||||
# 1.4.2
|
|
||||||
* Fixes build break for plan9, nacl, solaris
|
|
||||||
# 1.4.1
|
|
||||||
This new release introduces:
|
|
||||||
* Enhance TextFormatter to not print caller information when they are empty (#944)
|
|
||||||
* Remove dependency on golang.org/x/crypto (#932, #943)
|
|
||||||
|
|
||||||
Fixes:
|
|
||||||
* Fix Entry.WithContext method to return a copy of the initial entry (#941)
|
|
||||||
|
|
||||||
# 1.4.0
|
|
||||||
This new release introduces:
|
|
||||||
* Add `DeferExitHandler`, similar to `RegisterExitHandler` but prepending the handler to the list of handlers (semantically like `defer`) (#848).
|
|
||||||
* Add `CallerPrettyfier` to `JSONFormatter` and `TextFormatter` (#909, #911)
|
|
||||||
* Add `Entry.WithContext()` and `Entry.Context`, to set a context on entries to be used e.g. in hooks (#919).
|
|
||||||
|
|
||||||
Fixes:
|
|
||||||
* Fix wrong method calls `Logger.Print` and `Logger.Warningln` (#893).
|
|
||||||
* Update `Entry.Logf` to not do string formatting unless the log level is enabled (#903)
|
|
||||||
* Fix infinite recursion on unknown `Level.String()` (#907)
|
|
||||||
* Fix race condition in `getCaller` (#916).
|
|
||||||
|
|
||||||
|
|
||||||
# 1.3.0
|
|
||||||
This new release introduces:
|
|
||||||
* Log, Logf, Logln functions for Logger and Entry that take a Level
|
|
||||||
|
|
||||||
Fixes:
|
|
||||||
* Building prometheus node_exporter on AIX (#840)
|
|
||||||
* Race condition in TextFormatter (#468)
|
|
||||||
* Travis CI import path (#868)
|
|
||||||
* Remove coloured output on Windows (#862)
|
|
||||||
* Pointer to func as field in JSONFormatter (#870)
|
|
||||||
* Properly marshal Levels (#873)
|
|
||||||
|
|
||||||
# 1.2.0
|
|
||||||
This new release introduces:
|
|
||||||
* A new method `SetReportCaller` in the `Logger` to enable the file, line and calling function from which the trace has been issued
|
|
||||||
* A new trace level named `Trace` whose level is below `Debug`
|
|
||||||
* A configurable exit function to be called upon a Fatal trace
|
|
||||||
* The `Level` object now implements `encoding.TextUnmarshaler` interface
|
|
||||||
|
|
||||||
# 1.1.1
|
|
||||||
This is a bug fix release.
|
|
||||||
* fix the build break on Solaris
|
|
||||||
* don't drop a whole trace in JSONFormatter when a field param is a function pointer which can not be serialized
|
|
||||||
|
|
||||||
# 1.1.0
|
|
||||||
This new release introduces:
|
|
||||||
* several fixes:
|
|
||||||
* a fix for a race condition on entry formatting
|
|
||||||
* proper cleanup of previously used entries before putting them back in the pool
|
|
||||||
* the extra new line at the end of message in text formatter has been removed
|
|
||||||
* a new global public API to check if a level is activated: IsLevelEnabled
|
|
||||||
* the following methods have been added to the Logger object
|
|
||||||
* IsLevelEnabled
|
|
||||||
* SetFormatter
|
|
||||||
* SetOutput
|
|
||||||
* ReplaceHooks
|
|
||||||
* introduction of go module
|
|
||||||
* an indent configuration for the json formatter
|
|
||||||
* output colour support for windows
|
|
||||||
* the field sort function is now configurable for text formatter
|
|
||||||
* the CLICOLOR and CLICOLOR\_FORCE environment variable support in text formater
|
|
||||||
|
|
||||||
# 1.0.6
|
|
||||||
|
|
||||||
This new release introduces:
|
|
||||||
* a new api WithTime which allows to easily force the time of the log entry
|
|
||||||
which is mostly useful for logger wrapper
|
|
||||||
* a fix reverting the immutability of the entry given as parameter to the hooks
|
|
||||||
a new configuration field of the json formatter in order to put all the fields
|
|
||||||
in a nested dictionnary
|
|
||||||
* a new SetOutput method in the Logger
|
|
||||||
* a new configuration of the textformatter to configure the name of the default keys
|
|
||||||
* a new configuration of the text formatter to disable the level truncation
|
|
||||||
|
|
||||||
# 1.0.5
|
|
||||||
|
|
||||||
* Fix hooks race (#707)
|
|
||||||
* Fix panic deadlock (#695)
|
|
||||||
|
|
||||||
# 1.0.4
|
|
||||||
|
|
||||||
* Fix race when adding hooks (#612)
|
|
||||||
* Fix terminal check in AppEngine (#635)
|
|
||||||
|
|
||||||
# 1.0.3
|
|
||||||
|
|
||||||
* Replace example files with testable examples
|
|
||||||
|
|
||||||
# 1.0.2
|
|
||||||
|
|
||||||
* bug: quote non-string values in text formatter (#583)
|
|
||||||
* Make (*Logger) SetLevel a public method
|
|
||||||
|
|
||||||
# 1.0.1
|
|
||||||
|
|
||||||
* bug: fix escaping in text formatter (#575)
|
|
||||||
|
|
||||||
# 1.0.0
|
|
||||||
|
|
||||||
* Officially changed name to lower-case
|
|
||||||
* bug: colors on Windows 10 (#541)
|
|
||||||
* bug: fix race in accessing level (#512)
|
|
||||||
|
|
||||||
# 0.11.5
|
|
||||||
|
|
||||||
* feature: add writer and writerlevel to entry (#372)
|
|
||||||
|
|
||||||
# 0.11.4
|
|
||||||
|
|
||||||
* bug: fix undefined variable on solaris (#493)
|
|
||||||
|
|
||||||
# 0.11.3
|
|
||||||
|
|
||||||
* formatter: configure quoting of empty values (#484)
|
|
||||||
* formatter: configure quoting character (default is `"`) (#484)
|
|
||||||
* bug: fix not importing io correctly in non-linux environments (#481)
|
|
||||||
|
|
||||||
# 0.11.2
|
|
||||||
|
|
||||||
* bug: fix windows terminal detection (#476)
|
|
||||||
|
|
||||||
# 0.11.1
|
|
||||||
|
|
||||||
* bug: fix tty detection with custom out (#471)
|
|
||||||
|
|
||||||
# 0.11.0
|
|
||||||
|
|
||||||
* performance: Use bufferpool to allocate (#370)
|
|
||||||
* terminal: terminal detection for app-engine (#343)
|
|
||||||
* feature: exit handler (#375)
|
|
||||||
|
|
||||||
# 0.10.0
|
|
||||||
|
|
||||||
* feature: Add a test hook (#180)
|
|
||||||
* feature: `ParseLevel` is now case-insensitive (#326)
|
|
||||||
* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308)
|
|
||||||
* performance: avoid re-allocations on `WithFields` (#335)
|
|
||||||
|
|
||||||
# 0.9.0
|
|
||||||
|
|
||||||
* logrus/text_formatter: don't emit empty msg
|
|
||||||
* logrus/hooks/airbrake: move out of main repository
|
|
||||||
* logrus/hooks/sentry: move out of main repository
|
|
||||||
* logrus/hooks/papertrail: move out of main repository
|
|
||||||
* logrus/hooks/bugsnag: move out of main repository
|
|
||||||
* logrus/core: run tests with `-race`
|
|
||||||
* logrus/core: detect TTY based on `stderr`
|
|
||||||
* logrus/core: support `WithError` on logger
|
|
||||||
* logrus/core: Solaris support
|
|
||||||
|
|
||||||
# 0.8.7
|
|
||||||
|
|
||||||
* logrus/core: fix possible race (#216)
|
|
||||||
* logrus/doc: small typo fixes and doc improvements
|
|
||||||
|
|
||||||
|
|
||||||
# 0.8.6
|
|
||||||
|
|
||||||
* hooks/raven: allow passing an initialized client
|
|
||||||
|
|
||||||
# 0.8.5
|
|
||||||
|
|
||||||
* logrus/core: revert #208
|
|
||||||
|
|
||||||
# 0.8.4
|
|
||||||
|
|
||||||
* formatter/text: fix data race (#218)
|
|
||||||
|
|
||||||
# 0.8.3
|
|
||||||
|
|
||||||
* logrus/core: fix entry log level (#208)
|
|
||||||
* logrus/core: improve performance of text formatter by 40%
|
|
||||||
* logrus/core: expose `LevelHooks` type
|
|
||||||
* logrus/core: add support for DragonflyBSD and NetBSD
|
|
||||||
* formatter/text: print structs more verbosely
|
|
||||||
|
|
||||||
# 0.8.2
|
|
||||||
|
|
||||||
* logrus: fix more Fatal family functions
|
|
||||||
|
|
||||||
# 0.8.1
|
|
||||||
|
|
||||||
* logrus: fix not exiting on `Fatalf` and `Fatalln`
|
|
||||||
|
|
||||||
# 0.8.0
|
|
||||||
|
|
||||||
* logrus: defaults to stderr instead of stdout
|
|
||||||
* hooks/sentry: add special field for `*http.Request`
|
|
||||||
* formatter/text: ignore Windows for colors
|
|
||||||
|
|
||||||
# 0.7.3
|
|
||||||
|
|
||||||
* formatter/\*: allow configuration of timestamp layout
|
|
||||||
|
|
||||||
# 0.7.2
|
|
||||||
|
|
||||||
* formatter/text: Add configuration option for time format (#158)
|
|
||||||
21
vendor/github.com/sirupsen/logrus/LICENSE
generated
vendored
21
vendor/github.com/sirupsen/logrus/LICENSE
generated
vendored
@@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2014 Simon Eskildsen
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
513
vendor/github.com/sirupsen/logrus/README.md
generated
vendored
513
vendor/github.com/sirupsen/logrus/README.md
generated
vendored
@@ -1,513 +0,0 @@
|
|||||||
# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/> [](https://travis-ci.org/sirupsen/logrus) [](https://godoc.org/github.com/sirupsen/logrus)
|
|
||||||
|
|
||||||
Logrus is a structured logger for Go (golang), completely API compatible with
|
|
||||||
the standard library logger.
|
|
||||||
|
|
||||||
**Logrus is in maintenance-mode.** We will not be introducing new features. It's
|
|
||||||
simply too hard to do in a way that won't break many people's projects, which is
|
|
||||||
the last thing you want from your Logging library (again...).
|
|
||||||
|
|
||||||
This does not mean Logrus is dead. Logrus will continue to be maintained for
|
|
||||||
security, (backwards compatible) bug fixes, and performance (where we are
|
|
||||||
limited by the interface).
|
|
||||||
|
|
||||||
I believe Logrus' biggest contribution is to have played a part in today's
|
|
||||||
widespread use of structured logging in Golang. There doesn't seem to be a
|
|
||||||
reason to do a major, breaking iteration into Logrus V2, since the fantastic Go
|
|
||||||
community has built those independently. Many fantastic alternatives have sprung
|
|
||||||
up. Logrus would look like those, had it been re-designed with what we know
|
|
||||||
about structured logging in Go today. Check out, for example,
|
|
||||||
[Zerolog][zerolog], [Zap][zap], and [Apex][apex].
|
|
||||||
|
|
||||||
[zerolog]: https://github.com/rs/zerolog
|
|
||||||
[zap]: https://github.com/uber-go/zap
|
|
||||||
[apex]: https://github.com/apex/log
|
|
||||||
|
|
||||||
**Seeing weird case-sensitive problems?** It's in the past been possible to
|
|
||||||
import Logrus as both upper- and lower-case. Due to the Go package environment,
|
|
||||||
this caused issues in the community and we needed a standard. Some environments
|
|
||||||
experienced problems with the upper-case variant, so the lower-case was decided.
|
|
||||||
Everything using `logrus` will need to use the lower-case:
|
|
||||||
`github.com/sirupsen/logrus`. Any package that isn't, should be changed.
|
|
||||||
|
|
||||||
To fix Glide, see [these
|
|
||||||
comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437).
|
|
||||||
For an in-depth explanation of the casing issue, see [this
|
|
||||||
comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276).
|
|
||||||
|
|
||||||
Nicely color-coded in development (when a TTY is attached, otherwise just
|
|
||||||
plain text):
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
With `log.SetFormatter(&log.JSONFormatter{})`, for easy parsing by logstash
|
|
||||||
or Splunk:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the
|
|
||||||
ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}
|
|
||||||
|
|
||||||
{"level":"warning","msg":"The group's number increased tremendously!",
|
|
||||||
"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"}
|
|
||||||
|
|
||||||
{"animal":"walrus","level":"info","msg":"A giant walrus appears!",
|
|
||||||
"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"}
|
|
||||||
|
|
||||||
{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.",
|
|
||||||
"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"}
|
|
||||||
|
|
||||||
{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true,
|
|
||||||
"time":"2014-03-10 19:57:38.562543128 -0400 EDT"}
|
|
||||||
```
|
|
||||||
|
|
||||||
With the default `log.SetFormatter(&log.TextFormatter{})` when a TTY is not
|
|
||||||
attached, the output is compatible with the
|
|
||||||
[logfmt](http://godoc.org/github.com/kr/logfmt) format:
|
|
||||||
|
|
||||||
```text
|
|
||||||
time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
|
|
||||||
time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
|
|
||||||
time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true
|
|
||||||
time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4
|
|
||||||
time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009
|
|
||||||
time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true
|
|
||||||
```
|
|
||||||
To ensure this behaviour even if a TTY is attached, set your formatter as follows:
|
|
||||||
|
|
||||||
```go
|
|
||||||
log.SetFormatter(&log.TextFormatter{
|
|
||||||
DisableColors: true,
|
|
||||||
FullTimestamp: true,
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Logging Method Name
|
|
||||||
|
|
||||||
If you wish to add the calling method as a field, instruct the logger via:
|
|
||||||
```go
|
|
||||||
log.SetReportCaller(true)
|
|
||||||
```
|
|
||||||
This adds the caller as 'method' like so:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"animal":"penguin","level":"fatal","method":"github.com/sirupsen/arcticcreatures.migrate","msg":"a penguin swims by",
|
|
||||||
"time":"2014-03-10 19:57:38.562543129 -0400 EDT"}
|
|
||||||
```
|
|
||||||
|
|
||||||
```text
|
|
||||||
time="2015-03-26T01:27:38-04:00" level=fatal method=github.com/sirupsen/arcticcreatures.migrate msg="a penguin swims by" animal=penguin
|
|
||||||
```
|
|
||||||
Note that this does add measurable overhead - the cost will depend on the version of Go, but is
|
|
||||||
between 20 and 40% in recent tests with 1.6 and 1.7. You can validate this in your
|
|
||||||
environment via benchmarks:
|
|
||||||
```
|
|
||||||
go test -bench=.*CallerTracing
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
#### Case-sensitivity
|
|
||||||
|
|
||||||
The organization's name was changed to lower-case--and this will not be changed
|
|
||||||
back. If you are getting import conflicts due to case sensitivity, please use
|
|
||||||
the lower-case import: `github.com/sirupsen/logrus`.
|
|
||||||
|
|
||||||
#### Example
|
|
||||||
|
|
||||||
The simplest way to use Logrus is simply the package-level exported logger:
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"animal": "walrus",
|
|
||||||
}).Info("A walrus appears")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that it's completely api-compatible with the stdlib logger, so you can
|
|
||||||
replace your `log` imports everywhere with `log "github.com/sirupsen/logrus"`
|
|
||||||
and you'll now have the flexibility of Logrus. You can customize it all you
|
|
||||||
want:
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// Log as JSON instead of the default ASCII formatter.
|
|
||||||
log.SetFormatter(&log.JSONFormatter{})
|
|
||||||
|
|
||||||
// Output to stdout instead of the default stderr
|
|
||||||
// Can be any io.Writer, see below for File example
|
|
||||||
log.SetOutput(os.Stdout)
|
|
||||||
|
|
||||||
// Only log the warning severity or above.
|
|
||||||
log.SetLevel(log.WarnLevel)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"animal": "walrus",
|
|
||||||
"size": 10,
|
|
||||||
}).Info("A group of walrus emerges from the ocean")
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"omg": true,
|
|
||||||
"number": 122,
|
|
||||||
}).Warn("The group's number increased tremendously!")
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"omg": true,
|
|
||||||
"number": 100,
|
|
||||||
}).Fatal("The ice breaks!")
|
|
||||||
|
|
||||||
// A common pattern is to re-use fields between logging statements by re-using
|
|
||||||
// the logrus.Entry returned from WithFields()
|
|
||||||
contextLogger := log.WithFields(log.Fields{
|
|
||||||
"common": "this is a common field",
|
|
||||||
"other": "I also should be logged always",
|
|
||||||
})
|
|
||||||
|
|
||||||
contextLogger.Info("I'll be logged with common and other field")
|
|
||||||
contextLogger.Info("Me too")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
For more advanced usage such as logging to multiple locations from the same
|
|
||||||
application, you can also create an instance of the `logrus` Logger:
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Create a new instance of the logger. You can have any number of instances.
|
|
||||||
var log = logrus.New()
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// The API for setting attributes is a little different than the package level
|
|
||||||
// exported logger. See Godoc.
|
|
||||||
log.Out = os.Stdout
|
|
||||||
|
|
||||||
// You could set this to any `io.Writer` such as a file
|
|
||||||
// file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
|
||||||
// if err == nil {
|
|
||||||
// log.Out = file
|
|
||||||
// } else {
|
|
||||||
// log.Info("Failed to log to file, using default stderr")
|
|
||||||
// }
|
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"animal": "walrus",
|
|
||||||
"size": 10,
|
|
||||||
}).Info("A group of walrus emerges from the ocean")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Fields
|
|
||||||
|
|
||||||
Logrus encourages careful, structured logging through logging fields instead of
|
|
||||||
long, unparseable error messages. For example, instead of: `log.Fatalf("Failed
|
|
||||||
to send event %s to topic %s with key %d")`, you should log the much more
|
|
||||||
discoverable:
|
|
||||||
|
|
||||||
```go
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"event": event,
|
|
||||||
"topic": topic,
|
|
||||||
"key": key,
|
|
||||||
}).Fatal("Failed to send event")
|
|
||||||
```
|
|
||||||
|
|
||||||
We've found this API forces you to think about logging in a way that produces
|
|
||||||
much more useful logging messages. We've been in countless situations where just
|
|
||||||
a single added field to a log statement that was already there would've saved us
|
|
||||||
hours. The `WithFields` call is optional.
|
|
||||||
|
|
||||||
In general, with Logrus using any of the `printf`-family functions should be
|
|
||||||
seen as a hint you should add a field, however, you can still use the
|
|
||||||
`printf`-family functions with Logrus.
|
|
||||||
|
|
||||||
#### Default Fields
|
|
||||||
|
|
||||||
Often it's helpful to have fields _always_ attached to log statements in an
|
|
||||||
application or parts of one. For example, you may want to always log the
|
|
||||||
`request_id` and `user_ip` in the context of a request. Instead of writing
|
|
||||||
`log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})` on
|
|
||||||
every line, you can create a `logrus.Entry` to pass around instead:
|
|
||||||
|
|
||||||
```go
|
|
||||||
requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})
|
|
||||||
requestLogger.Info("something happened on that request") # will log request_id and user_ip
|
|
||||||
requestLogger.Warn("something not great happened")
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Hooks
|
|
||||||
|
|
||||||
You can add hooks for logging levels. For example to send errors to an exception
|
|
||||||
tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to
|
|
||||||
multiple places simultaneously, e.g. syslog.
|
|
||||||
|
|
||||||
Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in
|
|
||||||
`init`:
|
|
||||||
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "airbrake"
|
|
||||||
logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
|
|
||||||
"log/syslog"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
|
|
||||||
// Use the Airbrake hook to report errors that have Error severity or above to
|
|
||||||
// an exception tracker. You can create custom hooks, see the Hooks section.
|
|
||||||
log.AddHook(airbrake.NewHook(123, "xyz", "production"))
|
|
||||||
|
|
||||||
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Unable to connect to local syslog daemon")
|
|
||||||
} else {
|
|
||||||
log.AddHook(hook)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md).
|
|
||||||
|
|
||||||
A list of currently known service hooks can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks)
|
|
||||||
|
|
||||||
|
|
||||||
#### Level logging
|
|
||||||
|
|
||||||
Logrus has seven logging levels: Trace, Debug, Info, Warning, Error, Fatal and Panic.
|
|
||||||
|
|
||||||
```go
|
|
||||||
log.Trace("Something very low level.")
|
|
||||||
log.Debug("Useful debugging information.")
|
|
||||||
log.Info("Something noteworthy happened!")
|
|
||||||
log.Warn("You should probably take a look at this.")
|
|
||||||
log.Error("Something failed but I'm not quitting.")
|
|
||||||
// Calls os.Exit(1) after logging
|
|
||||||
log.Fatal("Bye.")
|
|
||||||
// Calls panic() after logging
|
|
||||||
log.Panic("I'm bailing.")
|
|
||||||
```
|
|
||||||
|
|
||||||
You can set the logging level on a `Logger`, then it will only log entries with
|
|
||||||
that severity or anything above it:
|
|
||||||
|
|
||||||
```go
|
|
||||||
// Will log anything that is info or above (warn, error, fatal, panic). Default.
|
|
||||||
log.SetLevel(log.InfoLevel)
|
|
||||||
```
|
|
||||||
|
|
||||||
It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose
|
|
||||||
environment if your application has that.
|
|
||||||
|
|
||||||
#### Entries
|
|
||||||
|
|
||||||
Besides the fields added with `WithField` or `WithFields` some fields are
|
|
||||||
automatically added to all logging events:
|
|
||||||
|
|
||||||
1. `time`. The timestamp when the entry was created.
|
|
||||||
2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after
|
|
||||||
the `AddFields` call. E.g. `Failed to send event.`
|
|
||||||
3. `level`. The logging level. E.g. `info`.
|
|
||||||
|
|
||||||
#### Environments
|
|
||||||
|
|
||||||
Logrus has no notion of environment.
|
|
||||||
|
|
||||||
If you wish for hooks and formatters to only be used in specific environments,
|
|
||||||
you should handle that yourself. For example, if your application has a global
|
|
||||||
variable `Environment`, which is a string representation of the environment you
|
|
||||||
could do:
|
|
||||||
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
init() {
|
|
||||||
// do something here to set environment depending on an environment variable
|
|
||||||
// or command-line flag
|
|
||||||
if Environment == "production" {
|
|
||||||
log.SetFormatter(&log.JSONFormatter{})
|
|
||||||
} else {
|
|
||||||
// The TextFormatter is default, you don't actually have to do this.
|
|
||||||
log.SetFormatter(&log.TextFormatter{})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This configuration is how `logrus` was intended to be used, but JSON in
|
|
||||||
production is mostly only useful if you do log aggregation with tools like
|
|
||||||
Splunk or Logstash.
|
|
||||||
|
|
||||||
#### Formatters
|
|
||||||
|
|
||||||
The built-in logging formatters are:
|
|
||||||
|
|
||||||
* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise
|
|
||||||
without colors.
|
|
||||||
* *Note:* to force colored output when there is no TTY, set the `ForceColors`
|
|
||||||
field to `true`. To force no colored output even if there is a TTY set the
|
|
||||||
`DisableColors` field to `true`. For Windows, see
|
|
||||||
[github.com/mattn/go-colorable](https://github.com/mattn/go-colorable).
|
|
||||||
* When colors are enabled, levels are truncated to 4 characters by default. To disable
|
|
||||||
truncation set the `DisableLevelTruncation` field to `true`.
|
|
||||||
* When outputting to a TTY, it's often helpful to visually scan down a column where all the levels are the same width. Setting the `PadLevelText` field to `true` enables this behavior, by adding padding to the level text.
|
|
||||||
* All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter).
|
|
||||||
* `logrus.JSONFormatter`. Logs fields as JSON.
|
|
||||||
* All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter).
|
|
||||||
|
|
||||||
Third party logging formatters:
|
|
||||||
|
|
||||||
* [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can be parsed by Kubernetes and Google Container Engine.
|
|
||||||
* [`GELF`](https://github.com/fabienm/go-logrus-formatters). Formats entries so they comply to Graylog's [GELF 1.1 specification](http://docs.graylog.org/en/2.4/pages/gelf.html).
|
|
||||||
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
|
|
||||||
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
|
|
||||||
* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the Power of Zalgo.
|
|
||||||
* [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure.
|
|
||||||
* [`powerful-logrus-formatter`](https://github.com/zput/zxcTool). get fileName, log's line number and the latest function's name when print log; Sava log to files.
|
|
||||||
* [`caption-json-formatter`](https://github.com/nolleh/caption_json_formatter). logrus's message json formatter with human-readable caption added.
|
|
||||||
|
|
||||||
You can define your formatter by implementing the `Formatter` interface,
|
|
||||||
requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
|
|
||||||
`Fields` type (`map[string]interface{}`) with all your fields as well as the
|
|
||||||
default ones (see Entries section above):
|
|
||||||
|
|
||||||
```go
|
|
||||||
type MyJSONFormatter struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
log.SetFormatter(new(MyJSONFormatter))
|
|
||||||
|
|
||||||
func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) {
|
|
||||||
// Note this doesn't include Time, Level and Message which are available on
|
|
||||||
// the Entry. Consult `godoc` on information about those fields or read the
|
|
||||||
// source of the official loggers.
|
|
||||||
serialized, err := json.Marshal(entry.Data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %w", err)
|
|
||||||
}
|
|
||||||
return append(serialized, '\n'), nil
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Logger as an `io.Writer`
|
|
||||||
|
|
||||||
Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it.
|
|
||||||
|
|
||||||
```go
|
|
||||||
w := logger.Writer()
|
|
||||||
defer w.Close()
|
|
||||||
|
|
||||||
srv := http.Server{
|
|
||||||
// create a stdlib log.Logger that writes to
|
|
||||||
// logrus.Logger.
|
|
||||||
ErrorLog: log.New(w, "", 0),
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Each line written to that writer will be printed the usual way, using formatters
|
|
||||||
and hooks. The level for those entries is `info`.
|
|
||||||
|
|
||||||
This means that we can override the standard library logger easily:
|
|
||||||
|
|
||||||
```go
|
|
||||||
logger := logrus.New()
|
|
||||||
logger.Formatter = &logrus.JSONFormatter{}
|
|
||||||
|
|
||||||
// Use logrus for standard log output
|
|
||||||
// Note that `log` here references stdlib's log
|
|
||||||
// Not logrus imported under the name `log`.
|
|
||||||
log.SetOutput(logger.Writer())
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Rotation
|
|
||||||
|
|
||||||
Log rotation is not provided with Logrus. Log rotation should be done by an
|
|
||||||
external program (like `logrotate(8)`) that can compress and delete old log
|
|
||||||
entries. It should not be a feature of the application-level logger.
|
|
||||||
|
|
||||||
#### Tools
|
|
||||||
|
|
||||||
| Tool | Description |
|
|
||||||
| ---- | ----------- |
|
|
||||||
|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will be generated with different configs in different environments.|
|
|
||||||
|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper around Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) |
|
|
||||||
|
|
||||||
#### Testing
|
|
||||||
|
|
||||||
Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides:
|
|
||||||
|
|
||||||
* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just adds the `test` hook
|
|
||||||
* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any):
|
|
||||||
|
|
||||||
```go
|
|
||||||
import(
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"github.com/sirupsen/logrus/hooks/test"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSomething(t*testing.T){
|
|
||||||
logger, hook := test.NewNullLogger()
|
|
||||||
logger.Error("Helloerror")
|
|
||||||
|
|
||||||
assert.Equal(t, 1, len(hook.Entries))
|
|
||||||
assert.Equal(t, logrus.ErrorLevel, hook.LastEntry().Level)
|
|
||||||
assert.Equal(t, "Helloerror", hook.LastEntry().Message)
|
|
||||||
|
|
||||||
hook.Reset()
|
|
||||||
assert.Nil(t, hook.LastEntry())
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Fatal handlers
|
|
||||||
|
|
||||||
Logrus can register one or more functions that will be called when any `fatal`
|
|
||||||
level message is logged. The registered handlers will be executed before
|
|
||||||
logrus performs an `os.Exit(1)`. This behavior may be helpful if callers need
|
|
||||||
to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted.
|
|
||||||
|
|
||||||
```
|
|
||||||
...
|
|
||||||
handler := func() {
|
|
||||||
// gracefully shutdown something...
|
|
||||||
}
|
|
||||||
logrus.RegisterExitHandler(handler)
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Thread safety
|
|
||||||
|
|
||||||
By default, Logger is protected by a mutex for concurrent writes. The mutex is held when calling hooks and writing logs.
|
|
||||||
If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking.
|
|
||||||
|
|
||||||
Situation when locking is not needed includes:
|
|
||||||
|
|
||||||
* You have no hooks registered, or hooks calling is already thread-safe.
|
|
||||||
|
|
||||||
* Writing to logger.Out is already thread-safe, for example:
|
|
||||||
|
|
||||||
1) logger.Out is protected by locks.
|
|
||||||
|
|
||||||
2) logger.Out is an os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allows multi-thread/multi-process writing)
|
|
||||||
|
|
||||||
(Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/)
|
|
||||||
76
vendor/github.com/sirupsen/logrus/alt_exit.go
generated
vendored
76
vendor/github.com/sirupsen/logrus/alt_exit.go
generated
vendored
@@ -1,76 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
// The following code was sourced and modified from the
|
|
||||||
// https://github.com/tebeka/atexit package governed by the following license:
|
|
||||||
//
|
|
||||||
// Copyright (c) 2012 Miki Tebeka <miki.tebeka@gmail.com>.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
// this software and associated documentation files (the "Software"), to deal in
|
|
||||||
// the Software without restriction, including without limitation the rights to
|
|
||||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
// subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
var handlers = []func(){}
|
|
||||||
|
|
||||||
func runHandler(handler func()) {
|
|
||||||
defer func() {
|
|
||||||
if err := recover(); err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
handler()
|
|
||||||
}
|
|
||||||
|
|
||||||
func runHandlers() {
|
|
||||||
for _, handler := range handlers {
|
|
||||||
runHandler(handler)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code)
|
|
||||||
func Exit(code int) {
|
|
||||||
runHandlers()
|
|
||||||
os.Exit(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterExitHandler appends a Logrus Exit handler to the list of handlers,
|
|
||||||
// call logrus.Exit to invoke all handlers. The handlers will also be invoked when
|
|
||||||
// any Fatal log entry is made.
|
|
||||||
//
|
|
||||||
// This method is useful when a caller wishes to use logrus to log a fatal
|
|
||||||
// message but also needs to gracefully shutdown. An example usecase could be
|
|
||||||
// closing database connections, or sending a alert that the application is
|
|
||||||
// closing.
|
|
||||||
func RegisterExitHandler(handler func()) {
|
|
||||||
handlers = append(handlers, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeferExitHandler prepends a Logrus Exit handler to the list of handlers,
|
|
||||||
// call logrus.Exit to invoke all handlers. The handlers will also be invoked when
|
|
||||||
// any Fatal log entry is made.
|
|
||||||
//
|
|
||||||
// This method is useful when a caller wishes to use logrus to log a fatal
|
|
||||||
// message but also needs to gracefully shutdown. An example usecase could be
|
|
||||||
// closing database connections, or sending a alert that the application is
|
|
||||||
// closing.
|
|
||||||
func DeferExitHandler(handler func()) {
|
|
||||||
handlers = append([]func(){handler}, handlers...)
|
|
||||||
}
|
|
||||||
14
vendor/github.com/sirupsen/logrus/appveyor.yml
generated
vendored
14
vendor/github.com/sirupsen/logrus/appveyor.yml
generated
vendored
@@ -1,14 +0,0 @@
|
|||||||
version: "{build}"
|
|
||||||
platform: x64
|
|
||||||
clone_folder: c:\gopath\src\github.com\sirupsen\logrus
|
|
||||||
environment:
|
|
||||||
GOPATH: c:\gopath
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
install:
|
|
||||||
- set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
|
|
||||||
- go version
|
|
||||||
build_script:
|
|
||||||
- go get -t
|
|
||||||
- go test
|
|
||||||
52
vendor/github.com/sirupsen/logrus/buffer_pool.go
generated
vendored
52
vendor/github.com/sirupsen/logrus/buffer_pool.go
generated
vendored
@@ -1,52 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
bufferPool BufferPool
|
|
||||||
)
|
|
||||||
|
|
||||||
type BufferPool interface {
|
|
||||||
Put(*bytes.Buffer)
|
|
||||||
Get() *bytes.Buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
type defaultPool struct {
|
|
||||||
pool *sync.Pool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *defaultPool) Put(buf *bytes.Buffer) {
|
|
||||||
p.pool.Put(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *defaultPool) Get() *bytes.Buffer {
|
|
||||||
return p.pool.Get().(*bytes.Buffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getBuffer() *bytes.Buffer {
|
|
||||||
return bufferPool.Get()
|
|
||||||
}
|
|
||||||
|
|
||||||
func putBuffer(buf *bytes.Buffer) {
|
|
||||||
buf.Reset()
|
|
||||||
bufferPool.Put(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetBufferPool allows to replace the default logrus buffer pool
|
|
||||||
// to better meets the specific needs of an application.
|
|
||||||
func SetBufferPool(bp BufferPool) {
|
|
||||||
bufferPool = bp
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
SetBufferPool(&defaultPool{
|
|
||||||
pool: &sync.Pool{
|
|
||||||
New: func() interface{} {
|
|
||||||
return new(bytes.Buffer)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
26
vendor/github.com/sirupsen/logrus/doc.go
generated
vendored
26
vendor/github.com/sirupsen/logrus/doc.go
generated
vendored
@@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
Package logrus is a structured logger for Go, completely API compatible with the standard library logger.
|
|
||||||
|
|
||||||
|
|
||||||
The simplest way to use Logrus is simply the package-level exported logger:
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"animal": "walrus",
|
|
||||||
"number": 1,
|
|
||||||
"size": 10,
|
|
||||||
}).Info("A walrus appears")
|
|
||||||
}
|
|
||||||
|
|
||||||
Output:
|
|
||||||
time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10
|
|
||||||
|
|
||||||
For a full guide visit https://github.com/sirupsen/logrus
|
|
||||||
*/
|
|
||||||
package logrus
|
|
||||||
431
vendor/github.com/sirupsen/logrus/entry.go
generated
vendored
431
vendor/github.com/sirupsen/logrus/entry.go
generated
vendored
@@ -1,431 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
|
|
||||||
// qualified package name, cached at first use
|
|
||||||
logrusPackage string
|
|
||||||
|
|
||||||
// Positions in the call stack when tracing to report the calling method
|
|
||||||
minimumCallerDepth int
|
|
||||||
|
|
||||||
// Used for caller information initialisation
|
|
||||||
callerInitOnce sync.Once
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
maximumCallerDepth int = 25
|
|
||||||
knownLogrusFrames int = 4
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// start at the bottom of the stack before the package-name cache is primed
|
|
||||||
minimumCallerDepth = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defines the key when adding errors using WithError.
|
|
||||||
var ErrorKey = "error"
|
|
||||||
|
|
||||||
// An entry is the final or intermediate Logrus logging entry. It contains all
|
|
||||||
// the fields passed with WithField{,s}. It's finally logged when Trace, Debug,
|
|
||||||
// Info, Warn, Error, Fatal or Panic is called on it. These objects can be
|
|
||||||
// reused and passed around as much as you wish to avoid field duplication.
|
|
||||||
type Entry struct {
|
|
||||||
Logger *Logger
|
|
||||||
|
|
||||||
// Contains all the fields set by the user.
|
|
||||||
Data Fields
|
|
||||||
|
|
||||||
// Time at which the log entry was created
|
|
||||||
Time time.Time
|
|
||||||
|
|
||||||
// Level the log entry was logged at: Trace, Debug, Info, Warn, Error, Fatal or Panic
|
|
||||||
// This field will be set on entry firing and the value will be equal to the one in Logger struct field.
|
|
||||||
Level Level
|
|
||||||
|
|
||||||
// Calling method, with package name
|
|
||||||
Caller *runtime.Frame
|
|
||||||
|
|
||||||
// Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic
|
|
||||||
Message string
|
|
||||||
|
|
||||||
// When formatter is called in entry.log(), a Buffer may be set to entry
|
|
||||||
Buffer *bytes.Buffer
|
|
||||||
|
|
||||||
// Contains the context set by the user. Useful for hook processing etc.
|
|
||||||
Context context.Context
|
|
||||||
|
|
||||||
// err may contain a field formatting error
|
|
||||||
err string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewEntry(logger *Logger) *Entry {
|
|
||||||
return &Entry{
|
|
||||||
Logger: logger,
|
|
||||||
// Default is three fields, plus one optional. Give a little extra room.
|
|
||||||
Data: make(Fields, 6),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Dup() *Entry {
|
|
||||||
data := make(Fields, len(entry.Data))
|
|
||||||
for k, v := range entry.Data {
|
|
||||||
data[k] = v
|
|
||||||
}
|
|
||||||
return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, Context: entry.Context, err: entry.err}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the bytes representation of this entry from the formatter.
|
|
||||||
func (entry *Entry) Bytes() ([]byte, error) {
|
|
||||||
return entry.Logger.Formatter.Format(entry)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the string representation from the reader and ultimately the
|
|
||||||
// formatter.
|
|
||||||
func (entry *Entry) String() (string, error) {
|
|
||||||
serialized, err := entry.Bytes()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
str := string(serialized)
|
|
||||||
return str, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add an error as single field (using the key defined in ErrorKey) to the Entry.
|
|
||||||
func (entry *Entry) WithError(err error) *Entry {
|
|
||||||
return entry.WithField(ErrorKey, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a context to the Entry.
|
|
||||||
func (entry *Entry) WithContext(ctx context.Context) *Entry {
|
|
||||||
dataCopy := make(Fields, len(entry.Data))
|
|
||||||
for k, v := range entry.Data {
|
|
||||||
dataCopy[k] = v
|
|
||||||
}
|
|
||||||
return &Entry{Logger: entry.Logger, Data: dataCopy, Time: entry.Time, err: entry.err, Context: ctx}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a single field to the Entry.
|
|
||||||
func (entry *Entry) WithField(key string, value interface{}) *Entry {
|
|
||||||
return entry.WithFields(Fields{key: value})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a map of fields to the Entry.
|
|
||||||
func (entry *Entry) WithFields(fields Fields) *Entry {
|
|
||||||
data := make(Fields, len(entry.Data)+len(fields))
|
|
||||||
for k, v := range entry.Data {
|
|
||||||
data[k] = v
|
|
||||||
}
|
|
||||||
fieldErr := entry.err
|
|
||||||
for k, v := range fields {
|
|
||||||
isErrField := false
|
|
||||||
if t := reflect.TypeOf(v); t != nil {
|
|
||||||
switch {
|
|
||||||
case t.Kind() == reflect.Func, t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Func:
|
|
||||||
isErrField = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if isErrField {
|
|
||||||
tmp := fmt.Sprintf("can not add field %q", k)
|
|
||||||
if fieldErr != "" {
|
|
||||||
fieldErr = entry.err + ", " + tmp
|
|
||||||
} else {
|
|
||||||
fieldErr = tmp
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
data[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr, Context: entry.Context}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overrides the time of the Entry.
|
|
||||||
func (entry *Entry) WithTime(t time.Time) *Entry {
|
|
||||||
dataCopy := make(Fields, len(entry.Data))
|
|
||||||
for k, v := range entry.Data {
|
|
||||||
dataCopy[k] = v
|
|
||||||
}
|
|
||||||
return &Entry{Logger: entry.Logger, Data: dataCopy, Time: t, err: entry.err, Context: entry.Context}
|
|
||||||
}
|
|
||||||
|
|
||||||
// getPackageName reduces a fully qualified function name to the package name
|
|
||||||
// There really ought to be to be a better way...
|
|
||||||
func getPackageName(f string) string {
|
|
||||||
for {
|
|
||||||
lastPeriod := strings.LastIndex(f, ".")
|
|
||||||
lastSlash := strings.LastIndex(f, "/")
|
|
||||||
if lastPeriod > lastSlash {
|
|
||||||
f = f[:lastPeriod]
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
// getCaller retrieves the name of the first non-logrus calling function
|
|
||||||
func getCaller() *runtime.Frame {
|
|
||||||
// cache this package's fully-qualified name
|
|
||||||
callerInitOnce.Do(func() {
|
|
||||||
pcs := make([]uintptr, maximumCallerDepth)
|
|
||||||
_ = runtime.Callers(0, pcs)
|
|
||||||
|
|
||||||
// dynamic get the package name and the minimum caller depth
|
|
||||||
for i := 0; i < maximumCallerDepth; i++ {
|
|
||||||
funcName := runtime.FuncForPC(pcs[i]).Name()
|
|
||||||
if strings.Contains(funcName, "getCaller") {
|
|
||||||
logrusPackage = getPackageName(funcName)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
minimumCallerDepth = knownLogrusFrames
|
|
||||||
})
|
|
||||||
|
|
||||||
// Restrict the lookback frames to avoid runaway lookups
|
|
||||||
pcs := make([]uintptr, maximumCallerDepth)
|
|
||||||
depth := runtime.Callers(minimumCallerDepth, pcs)
|
|
||||||
frames := runtime.CallersFrames(pcs[:depth])
|
|
||||||
|
|
||||||
for f, again := frames.Next(); again; f, again = frames.Next() {
|
|
||||||
pkg := getPackageName(f.Function)
|
|
||||||
|
|
||||||
// If the caller isn't part of this package, we're done
|
|
||||||
if pkg != logrusPackage {
|
|
||||||
return &f //nolint:scopelint
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we got here, we failed to find the caller's context
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry Entry) HasCaller() (has bool) {
|
|
||||||
return entry.Logger != nil &&
|
|
||||||
entry.Logger.ReportCaller &&
|
|
||||||
entry.Caller != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) log(level Level, msg string) {
|
|
||||||
var buffer *bytes.Buffer
|
|
||||||
|
|
||||||
newEntry := entry.Dup()
|
|
||||||
|
|
||||||
if newEntry.Time.IsZero() {
|
|
||||||
newEntry.Time = time.Now()
|
|
||||||
}
|
|
||||||
|
|
||||||
newEntry.Level = level
|
|
||||||
newEntry.Message = msg
|
|
||||||
|
|
||||||
newEntry.Logger.mu.Lock()
|
|
||||||
reportCaller := newEntry.Logger.ReportCaller
|
|
||||||
newEntry.Logger.mu.Unlock()
|
|
||||||
|
|
||||||
if reportCaller {
|
|
||||||
newEntry.Caller = getCaller()
|
|
||||||
}
|
|
||||||
|
|
||||||
newEntry.fireHooks()
|
|
||||||
|
|
||||||
buffer = getBuffer()
|
|
||||||
defer func() {
|
|
||||||
newEntry.Buffer = nil
|
|
||||||
putBuffer(buffer)
|
|
||||||
}()
|
|
||||||
buffer.Reset()
|
|
||||||
newEntry.Buffer = buffer
|
|
||||||
|
|
||||||
newEntry.write()
|
|
||||||
|
|
||||||
newEntry.Buffer = nil
|
|
||||||
|
|
||||||
// To avoid Entry#log() returning a value that only would make sense for
|
|
||||||
// panic() to use in Entry#Panic(), we avoid the allocation by checking
|
|
||||||
// directly here.
|
|
||||||
if level <= PanicLevel {
|
|
||||||
panic(newEntry)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) fireHooks() {
|
|
||||||
var tmpHooks LevelHooks
|
|
||||||
entry.Logger.mu.Lock()
|
|
||||||
tmpHooks = make(LevelHooks, len(entry.Logger.Hooks))
|
|
||||||
for k, v := range entry.Logger.Hooks {
|
|
||||||
tmpHooks[k] = v
|
|
||||||
}
|
|
||||||
entry.Logger.mu.Unlock()
|
|
||||||
|
|
||||||
err := tmpHooks.Fire(entry.Level, entry)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) write() {
|
|
||||||
serialized, err := entry.Logger.Formatter.Format(entry)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
entry.Logger.mu.Lock()
|
|
||||||
defer entry.Logger.mu.Unlock()
|
|
||||||
if _, err := entry.Logger.Out.Write(serialized); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Log(level Level, args ...interface{}) {
|
|
||||||
if entry.Logger.IsLevelEnabled(level) {
|
|
||||||
entry.log(level, fmt.Sprint(args...))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Trace(args ...interface{}) {
|
|
||||||
entry.Log(TraceLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Debug(args ...interface{}) {
|
|
||||||
entry.Log(DebugLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Print(args ...interface{}) {
|
|
||||||
entry.Info(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Info(args ...interface{}) {
|
|
||||||
entry.Log(InfoLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Warn(args ...interface{}) {
|
|
||||||
entry.Log(WarnLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Warning(args ...interface{}) {
|
|
||||||
entry.Warn(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Error(args ...interface{}) {
|
|
||||||
entry.Log(ErrorLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Fatal(args ...interface{}) {
|
|
||||||
entry.Log(FatalLevel, args...)
|
|
||||||
entry.Logger.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Panic(args ...interface{}) {
|
|
||||||
entry.Log(PanicLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entry Printf family functions
|
|
||||||
|
|
||||||
func (entry *Entry) Logf(level Level, format string, args ...interface{}) {
|
|
||||||
if entry.Logger.IsLevelEnabled(level) {
|
|
||||||
entry.Log(level, fmt.Sprintf(format, args...))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Tracef(format string, args ...interface{}) {
|
|
||||||
entry.Logf(TraceLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Debugf(format string, args ...interface{}) {
|
|
||||||
entry.Logf(DebugLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Infof(format string, args ...interface{}) {
|
|
||||||
entry.Logf(InfoLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Printf(format string, args ...interface{}) {
|
|
||||||
entry.Infof(format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Warnf(format string, args ...interface{}) {
|
|
||||||
entry.Logf(WarnLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Warningf(format string, args ...interface{}) {
|
|
||||||
entry.Warnf(format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Errorf(format string, args ...interface{}) {
|
|
||||||
entry.Logf(ErrorLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Fatalf(format string, args ...interface{}) {
|
|
||||||
entry.Logf(FatalLevel, format, args...)
|
|
||||||
entry.Logger.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Panicf(format string, args ...interface{}) {
|
|
||||||
entry.Logf(PanicLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entry Println family functions
|
|
||||||
|
|
||||||
func (entry *Entry) Logln(level Level, args ...interface{}) {
|
|
||||||
if entry.Logger.IsLevelEnabled(level) {
|
|
||||||
entry.Log(level, entry.sprintlnn(args...))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Traceln(args ...interface{}) {
|
|
||||||
entry.Logln(TraceLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Debugln(args ...interface{}) {
|
|
||||||
entry.Logln(DebugLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Infoln(args ...interface{}) {
|
|
||||||
entry.Logln(InfoLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Println(args ...interface{}) {
|
|
||||||
entry.Infoln(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Warnln(args ...interface{}) {
|
|
||||||
entry.Logln(WarnLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Warningln(args ...interface{}) {
|
|
||||||
entry.Warnln(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Errorln(args ...interface{}) {
|
|
||||||
entry.Logln(ErrorLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Fatalln(args ...interface{}) {
|
|
||||||
entry.Logln(FatalLevel, args...)
|
|
||||||
entry.Logger.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Panicln(args ...interface{}) {
|
|
||||||
entry.Logln(PanicLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sprintlnn => Sprint no newline. This is to get the behavior of how
|
|
||||||
// fmt.Sprintln where spaces are always added between operands, regardless of
|
|
||||||
// their type. Instead of vendoring the Sprintln implementation to spare a
|
|
||||||
// string allocation, we do the simplest thing.
|
|
||||||
func (entry *Entry) sprintlnn(args ...interface{}) string {
|
|
||||||
msg := fmt.Sprintln(args...)
|
|
||||||
return msg[:len(msg)-1]
|
|
||||||
}
|
|
||||||
270
vendor/github.com/sirupsen/logrus/exported.go
generated
vendored
270
vendor/github.com/sirupsen/logrus/exported.go
generated
vendored
@@ -1,270 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"io"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// std is the name of the standard logger in stdlib `log`
|
|
||||||
std = New()
|
|
||||||
)
|
|
||||||
|
|
||||||
func StandardLogger() *Logger {
|
|
||||||
return std
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetOutput sets the standard logger output.
|
|
||||||
func SetOutput(out io.Writer) {
|
|
||||||
std.SetOutput(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFormatter sets the standard logger formatter.
|
|
||||||
func SetFormatter(formatter Formatter) {
|
|
||||||
std.SetFormatter(formatter)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetReportCaller sets whether the standard logger will include the calling
|
|
||||||
// method as a field.
|
|
||||||
func SetReportCaller(include bool) {
|
|
||||||
std.SetReportCaller(include)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetLevel sets the standard logger level.
|
|
||||||
func SetLevel(level Level) {
|
|
||||||
std.SetLevel(level)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetLevel returns the standard logger level.
|
|
||||||
func GetLevel() Level {
|
|
||||||
return std.GetLevel()
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsLevelEnabled checks if the log level of the standard logger is greater than the level param
|
|
||||||
func IsLevelEnabled(level Level) bool {
|
|
||||||
return std.IsLevelEnabled(level)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddHook adds a hook to the standard logger hooks.
|
|
||||||
func AddHook(hook Hook) {
|
|
||||||
std.AddHook(hook)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key.
|
|
||||||
func WithError(err error) *Entry {
|
|
||||||
return std.WithField(ErrorKey, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithContext creates an entry from the standard logger and adds a context to it.
|
|
||||||
func WithContext(ctx context.Context) *Entry {
|
|
||||||
return std.WithContext(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithField creates an entry from the standard logger and adds a field to
|
|
||||||
// it. If you want multiple fields, use `WithFields`.
|
|
||||||
//
|
|
||||||
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
|
|
||||||
// or Panic on the Entry it returns.
|
|
||||||
func WithField(key string, value interface{}) *Entry {
|
|
||||||
return std.WithField(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithFields creates an entry from the standard logger and adds multiple
|
|
||||||
// fields to it. This is simply a helper for `WithField`, invoking it
|
|
||||||
// once for each field.
|
|
||||||
//
|
|
||||||
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
|
|
||||||
// or Panic on the Entry it returns.
|
|
||||||
func WithFields(fields Fields) *Entry {
|
|
||||||
return std.WithFields(fields)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithTime creates an entry from the standard logger and overrides the time of
|
|
||||||
// logs generated with it.
|
|
||||||
//
|
|
||||||
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
|
|
||||||
// or Panic on the Entry it returns.
|
|
||||||
func WithTime(t time.Time) *Entry {
|
|
||||||
return std.WithTime(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trace logs a message at level Trace on the standard logger.
|
|
||||||
func Trace(args ...interface{}) {
|
|
||||||
std.Trace(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug logs a message at level Debug on the standard logger.
|
|
||||||
func Debug(args ...interface{}) {
|
|
||||||
std.Debug(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print logs a message at level Info on the standard logger.
|
|
||||||
func Print(args ...interface{}) {
|
|
||||||
std.Print(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Info logs a message at level Info on the standard logger.
|
|
||||||
func Info(args ...interface{}) {
|
|
||||||
std.Info(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warn logs a message at level Warn on the standard logger.
|
|
||||||
func Warn(args ...interface{}) {
|
|
||||||
std.Warn(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warning logs a message at level Warn on the standard logger.
|
|
||||||
func Warning(args ...interface{}) {
|
|
||||||
std.Warning(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error logs a message at level Error on the standard logger.
|
|
||||||
func Error(args ...interface{}) {
|
|
||||||
std.Error(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Panic logs a message at level Panic on the standard logger.
|
|
||||||
func Panic(args ...interface{}) {
|
|
||||||
std.Panic(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fatal logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
|
|
||||||
func Fatal(args ...interface{}) {
|
|
||||||
std.Fatal(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TraceFn logs a message from a func at level Trace on the standard logger.
|
|
||||||
func TraceFn(fn LogFunction) {
|
|
||||||
std.TraceFn(fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DebugFn logs a message from a func at level Debug on the standard logger.
|
|
||||||
func DebugFn(fn LogFunction) {
|
|
||||||
std.DebugFn(fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrintFn logs a message from a func at level Info on the standard logger.
|
|
||||||
func PrintFn(fn LogFunction) {
|
|
||||||
std.PrintFn(fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InfoFn logs a message from a func at level Info on the standard logger.
|
|
||||||
func InfoFn(fn LogFunction) {
|
|
||||||
std.InfoFn(fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WarnFn logs a message from a func at level Warn on the standard logger.
|
|
||||||
func WarnFn(fn LogFunction) {
|
|
||||||
std.WarnFn(fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WarningFn logs a message from a func at level Warn on the standard logger.
|
|
||||||
func WarningFn(fn LogFunction) {
|
|
||||||
std.WarningFn(fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrorFn logs a message from a func at level Error on the standard logger.
|
|
||||||
func ErrorFn(fn LogFunction) {
|
|
||||||
std.ErrorFn(fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PanicFn logs a message from a func at level Panic on the standard logger.
|
|
||||||
func PanicFn(fn LogFunction) {
|
|
||||||
std.PanicFn(fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FatalFn logs a message from a func at level Fatal on the standard logger then the process will exit with status set to 1.
|
|
||||||
func FatalFn(fn LogFunction) {
|
|
||||||
std.FatalFn(fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tracef logs a message at level Trace on the standard logger.
|
|
||||||
func Tracef(format string, args ...interface{}) {
|
|
||||||
std.Tracef(format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debugf logs a message at level Debug on the standard logger.
|
|
||||||
func Debugf(format string, args ...interface{}) {
|
|
||||||
std.Debugf(format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Printf logs a message at level Info on the standard logger.
|
|
||||||
func Printf(format string, args ...interface{}) {
|
|
||||||
std.Printf(format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Infof logs a message at level Info on the standard logger.
|
|
||||||
func Infof(format string, args ...interface{}) {
|
|
||||||
std.Infof(format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warnf logs a message at level Warn on the standard logger.
|
|
||||||
func Warnf(format string, args ...interface{}) {
|
|
||||||
std.Warnf(format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warningf logs a message at level Warn on the standard logger.
|
|
||||||
func Warningf(format string, args ...interface{}) {
|
|
||||||
std.Warningf(format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Errorf logs a message at level Error on the standard logger.
|
|
||||||
func Errorf(format string, args ...interface{}) {
|
|
||||||
std.Errorf(format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Panicf logs a message at level Panic on the standard logger.
|
|
||||||
func Panicf(format string, args ...interface{}) {
|
|
||||||
std.Panicf(format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fatalf logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
|
|
||||||
func Fatalf(format string, args ...interface{}) {
|
|
||||||
std.Fatalf(format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Traceln logs a message at level Trace on the standard logger.
|
|
||||||
func Traceln(args ...interface{}) {
|
|
||||||
std.Traceln(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debugln logs a message at level Debug on the standard logger.
|
|
||||||
func Debugln(args ...interface{}) {
|
|
||||||
std.Debugln(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Println logs a message at level Info on the standard logger.
|
|
||||||
func Println(args ...interface{}) {
|
|
||||||
std.Println(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Infoln logs a message at level Info on the standard logger.
|
|
||||||
func Infoln(args ...interface{}) {
|
|
||||||
std.Infoln(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warnln logs a message at level Warn on the standard logger.
|
|
||||||
func Warnln(args ...interface{}) {
|
|
||||||
std.Warnln(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warningln logs a message at level Warn on the standard logger.
|
|
||||||
func Warningln(args ...interface{}) {
|
|
||||||
std.Warningln(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Errorln logs a message at level Error on the standard logger.
|
|
||||||
func Errorln(args ...interface{}) {
|
|
||||||
std.Errorln(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Panicln logs a message at level Panic on the standard logger.
|
|
||||||
func Panicln(args ...interface{}) {
|
|
||||||
std.Panicln(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fatalln logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
|
|
||||||
func Fatalln(args ...interface{}) {
|
|
||||||
std.Fatalln(args...)
|
|
||||||
}
|
|
||||||
78
vendor/github.com/sirupsen/logrus/formatter.go
generated
vendored
78
vendor/github.com/sirupsen/logrus/formatter.go
generated
vendored
@@ -1,78 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
// Default key names for the default fields
|
|
||||||
const (
|
|
||||||
defaultTimestampFormat = time.RFC3339
|
|
||||||
FieldKeyMsg = "msg"
|
|
||||||
FieldKeyLevel = "level"
|
|
||||||
FieldKeyTime = "time"
|
|
||||||
FieldKeyLogrusError = "logrus_error"
|
|
||||||
FieldKeyFunc = "func"
|
|
||||||
FieldKeyFile = "file"
|
|
||||||
)
|
|
||||||
|
|
||||||
// The Formatter interface is used to implement a custom Formatter. It takes an
|
|
||||||
// `Entry`. It exposes all the fields, including the default ones:
|
|
||||||
//
|
|
||||||
// * `entry.Data["msg"]`. The message passed from Info, Warn, Error ..
|
|
||||||
// * `entry.Data["time"]`. The timestamp.
|
|
||||||
// * `entry.Data["level"]. The level the entry was logged at.
|
|
||||||
//
|
|
||||||
// Any additional fields added with `WithField` or `WithFields` are also in
|
|
||||||
// `entry.Data`. Format is expected to return an array of bytes which are then
|
|
||||||
// logged to `logger.Out`.
|
|
||||||
type Formatter interface {
|
|
||||||
Format(*Entry) ([]byte, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is to not silently overwrite `time`, `msg`, `func` and `level` fields when
|
|
||||||
// dumping it. If this code wasn't there doing:
|
|
||||||
//
|
|
||||||
// logrus.WithField("level", 1).Info("hello")
|
|
||||||
//
|
|
||||||
// Would just silently drop the user provided level. Instead with this code
|
|
||||||
// it'll logged as:
|
|
||||||
//
|
|
||||||
// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
|
|
||||||
//
|
|
||||||
// It's not exported because it's still using Data in an opinionated way. It's to
|
|
||||||
// avoid code duplication between the two default formatters.
|
|
||||||
func prefixFieldClashes(data Fields, fieldMap FieldMap, reportCaller bool) {
|
|
||||||
timeKey := fieldMap.resolve(FieldKeyTime)
|
|
||||||
if t, ok := data[timeKey]; ok {
|
|
||||||
data["fields."+timeKey] = t
|
|
||||||
delete(data, timeKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
msgKey := fieldMap.resolve(FieldKeyMsg)
|
|
||||||
if m, ok := data[msgKey]; ok {
|
|
||||||
data["fields."+msgKey] = m
|
|
||||||
delete(data, msgKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
levelKey := fieldMap.resolve(FieldKeyLevel)
|
|
||||||
if l, ok := data[levelKey]; ok {
|
|
||||||
data["fields."+levelKey] = l
|
|
||||||
delete(data, levelKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
logrusErrKey := fieldMap.resolve(FieldKeyLogrusError)
|
|
||||||
if l, ok := data[logrusErrKey]; ok {
|
|
||||||
data["fields."+logrusErrKey] = l
|
|
||||||
delete(data, logrusErrKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If reportCaller is not set, 'func' will not conflict.
|
|
||||||
if reportCaller {
|
|
||||||
funcKey := fieldMap.resolve(FieldKeyFunc)
|
|
||||||
if l, ok := data[funcKey]; ok {
|
|
||||||
data["fields."+funcKey] = l
|
|
||||||
}
|
|
||||||
fileKey := fieldMap.resolve(FieldKeyFile)
|
|
||||||
if l, ok := data[fileKey]; ok {
|
|
||||||
data["fields."+fileKey] = l
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
34
vendor/github.com/sirupsen/logrus/hooks.go
generated
vendored
34
vendor/github.com/sirupsen/logrus/hooks.go
generated
vendored
@@ -1,34 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
// A hook to be fired when logging on the logging levels returned from
|
|
||||||
// `Levels()` on your implementation of the interface. Note that this is not
|
|
||||||
// fired in a goroutine or a channel with workers, you should handle such
|
|
||||||
// functionality yourself if your call is non-blocking and you don't wish for
|
|
||||||
// the logging calls for levels returned from `Levels()` to block.
|
|
||||||
type Hook interface {
|
|
||||||
Levels() []Level
|
|
||||||
Fire(*Entry) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Internal type for storing the hooks on a logger instance.
|
|
||||||
type LevelHooks map[Level][]Hook
|
|
||||||
|
|
||||||
// Add a hook to an instance of logger. This is called with
|
|
||||||
// `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface.
|
|
||||||
func (hooks LevelHooks) Add(hook Hook) {
|
|
||||||
for _, level := range hook.Levels() {
|
|
||||||
hooks[level] = append(hooks[level], hook)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fire all the hooks for the passed level. Used by `entry.log` to fire
|
|
||||||
// appropriate hooks for a log entry.
|
|
||||||
func (hooks LevelHooks) Fire(level Level, entry *Entry) error {
|
|
||||||
for _, hook := range hooks[level] {
|
|
||||||
if err := hook.Fire(entry); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
128
vendor/github.com/sirupsen/logrus/json_formatter.go
generated
vendored
128
vendor/github.com/sirupsen/logrus/json_formatter.go
generated
vendored
@@ -1,128 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
type fieldKey string
|
|
||||||
|
|
||||||
// FieldMap allows customization of the key names for default fields.
|
|
||||||
type FieldMap map[fieldKey]string
|
|
||||||
|
|
||||||
func (f FieldMap) resolve(key fieldKey) string {
|
|
||||||
if k, ok := f[key]; ok {
|
|
||||||
return k
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// JSONFormatter formats logs into parsable json
|
|
||||||
type JSONFormatter struct {
|
|
||||||
// TimestampFormat sets the format used for marshaling timestamps.
|
|
||||||
// The format to use is the same than for time.Format or time.Parse from the standard
|
|
||||||
// library.
|
|
||||||
// The standard Library already provides a set of predefined format.
|
|
||||||
TimestampFormat string
|
|
||||||
|
|
||||||
// DisableTimestamp allows disabling automatic timestamps in output
|
|
||||||
DisableTimestamp bool
|
|
||||||
|
|
||||||
// DisableHTMLEscape allows disabling html escaping in output
|
|
||||||
DisableHTMLEscape bool
|
|
||||||
|
|
||||||
// DataKey allows users to put all the log entry parameters into a nested dictionary at a given key.
|
|
||||||
DataKey string
|
|
||||||
|
|
||||||
// FieldMap allows users to customize the names of keys for default fields.
|
|
||||||
// As an example:
|
|
||||||
// formatter := &JSONFormatter{
|
|
||||||
// FieldMap: FieldMap{
|
|
||||||
// FieldKeyTime: "@timestamp",
|
|
||||||
// FieldKeyLevel: "@level",
|
|
||||||
// FieldKeyMsg: "@message",
|
|
||||||
// FieldKeyFunc: "@caller",
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
FieldMap FieldMap
|
|
||||||
|
|
||||||
// CallerPrettyfier can be set by the user to modify the content
|
|
||||||
// of the function and file keys in the json data when ReportCaller is
|
|
||||||
// activated. If any of the returned value is the empty string the
|
|
||||||
// corresponding key will be removed from json fields.
|
|
||||||
CallerPrettyfier func(*runtime.Frame) (function string, file string)
|
|
||||||
|
|
||||||
// PrettyPrint will indent all json logs
|
|
||||||
PrettyPrint bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format renders a single log entry
|
|
||||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
|
||||||
data := make(Fields, len(entry.Data)+4)
|
|
||||||
for k, v := range entry.Data {
|
|
||||||
switch v := v.(type) {
|
|
||||||
case error:
|
|
||||||
// Otherwise errors are ignored by `encoding/json`
|
|
||||||
// https://github.com/sirupsen/logrus/issues/137
|
|
||||||
data[k] = v.Error()
|
|
||||||
default:
|
|
||||||
data[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if f.DataKey != "" {
|
|
||||||
newData := make(Fields, 4)
|
|
||||||
newData[f.DataKey] = data
|
|
||||||
data = newData
|
|
||||||
}
|
|
||||||
|
|
||||||
prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
|
|
||||||
|
|
||||||
timestampFormat := f.TimestampFormat
|
|
||||||
if timestampFormat == "" {
|
|
||||||
timestampFormat = defaultTimestampFormat
|
|
||||||
}
|
|
||||||
|
|
||||||
if entry.err != "" {
|
|
||||||
data[f.FieldMap.resolve(FieldKeyLogrusError)] = entry.err
|
|
||||||
}
|
|
||||||
if !f.DisableTimestamp {
|
|
||||||
data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
|
|
||||||
}
|
|
||||||
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
|
|
||||||
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
|
|
||||||
if entry.HasCaller() {
|
|
||||||
funcVal := entry.Caller.Function
|
|
||||||
fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
|
|
||||||
if f.CallerPrettyfier != nil {
|
|
||||||
funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
|
|
||||||
}
|
|
||||||
if funcVal != "" {
|
|
||||||
data[f.FieldMap.resolve(FieldKeyFunc)] = funcVal
|
|
||||||
}
|
|
||||||
if fileVal != "" {
|
|
||||||
data[f.FieldMap.resolve(FieldKeyFile)] = fileVal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var b *bytes.Buffer
|
|
||||||
if entry.Buffer != nil {
|
|
||||||
b = entry.Buffer
|
|
||||||
} else {
|
|
||||||
b = &bytes.Buffer{}
|
|
||||||
}
|
|
||||||
|
|
||||||
encoder := json.NewEncoder(b)
|
|
||||||
encoder.SetEscapeHTML(!f.DisableHTMLEscape)
|
|
||||||
if f.PrettyPrint {
|
|
||||||
encoder.SetIndent("", " ")
|
|
||||||
}
|
|
||||||
if err := encoder.Encode(data); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to marshal fields to JSON, %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return b.Bytes(), nil
|
|
||||||
}
|
|
||||||
404
vendor/github.com/sirupsen/logrus/logger.go
generated
vendored
404
vendor/github.com/sirupsen/logrus/logger.go
generated
vendored
@@ -1,404 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LogFunction For big messages, it can be more efficient to pass a function
|
|
||||||
// and only call it if the log level is actually enables rather than
|
|
||||||
// generating the log message and then checking if the level is enabled
|
|
||||||
type LogFunction func() []interface{}
|
|
||||||
|
|
||||||
type Logger struct {
|
|
||||||
// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
|
|
||||||
// file, or leave it default which is `os.Stderr`. You can also set this to
|
|
||||||
// something more adventurous, such as logging to Kafka.
|
|
||||||
Out io.Writer
|
|
||||||
// Hooks for the logger instance. These allow firing events based on logging
|
|
||||||
// levels and log entries. For example, to send errors to an error tracking
|
|
||||||
// service, log to StatsD or dump the core on fatal errors.
|
|
||||||
Hooks LevelHooks
|
|
||||||
// All log entries pass through the formatter before logged to Out. The
|
|
||||||
// included formatters are `TextFormatter` and `JSONFormatter` for which
|
|
||||||
// TextFormatter is the default. In development (when a TTY is attached) it
|
|
||||||
// logs with colors, but to a file it wouldn't. You can easily implement your
|
|
||||||
// own that implements the `Formatter` interface, see the `README` or included
|
|
||||||
// formatters for examples.
|
|
||||||
Formatter Formatter
|
|
||||||
|
|
||||||
// Flag for whether to log caller info (off by default)
|
|
||||||
ReportCaller bool
|
|
||||||
|
|
||||||
// The logging level the logger should log at. This is typically (and defaults
|
|
||||||
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
|
||||||
// logged.
|
|
||||||
Level Level
|
|
||||||
// Used to sync writing to the log. Locking is enabled by Default
|
|
||||||
mu MutexWrap
|
|
||||||
// Reusable empty entry
|
|
||||||
entryPool sync.Pool
|
|
||||||
// Function to exit the application, defaults to `os.Exit()`
|
|
||||||
ExitFunc exitFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
type exitFunc func(int)
|
|
||||||
|
|
||||||
type MutexWrap struct {
|
|
||||||
lock sync.Mutex
|
|
||||||
disabled bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mw *MutexWrap) Lock() {
|
|
||||||
if !mw.disabled {
|
|
||||||
mw.lock.Lock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mw *MutexWrap) Unlock() {
|
|
||||||
if !mw.disabled {
|
|
||||||
mw.lock.Unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mw *MutexWrap) Disable() {
|
|
||||||
mw.disabled = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a new logger. Configuration should be set by changing `Formatter`,
|
|
||||||
// `Out` and `Hooks` directly on the default logger instance. You can also just
|
|
||||||
// instantiate your own:
|
|
||||||
//
|
|
||||||
// var log = &logrus.Logger{
|
|
||||||
// Out: os.Stderr,
|
|
||||||
// Formatter: new(logrus.TextFormatter),
|
|
||||||
// Hooks: make(logrus.LevelHooks),
|
|
||||||
// Level: logrus.DebugLevel,
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// It's recommended to make this a global instance called `log`.
|
|
||||||
func New() *Logger {
|
|
||||||
return &Logger{
|
|
||||||
Out: os.Stderr,
|
|
||||||
Formatter: new(TextFormatter),
|
|
||||||
Hooks: make(LevelHooks),
|
|
||||||
Level: InfoLevel,
|
|
||||||
ExitFunc: os.Exit,
|
|
||||||
ReportCaller: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) newEntry() *Entry {
|
|
||||||
entry, ok := logger.entryPool.Get().(*Entry)
|
|
||||||
if ok {
|
|
||||||
return entry
|
|
||||||
}
|
|
||||||
return NewEntry(logger)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) releaseEntry(entry *Entry) {
|
|
||||||
entry.Data = map[string]interface{}{}
|
|
||||||
logger.entryPool.Put(entry)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithField allocates a new entry and adds a field to it.
|
|
||||||
// Debug, Print, Info, Warn, Error, Fatal or Panic must be then applied to
|
|
||||||
// this new returned entry.
|
|
||||||
// If you want multiple fields, use `WithFields`.
|
|
||||||
func (logger *Logger) WithField(key string, value interface{}) *Entry {
|
|
||||||
entry := logger.newEntry()
|
|
||||||
defer logger.releaseEntry(entry)
|
|
||||||
return entry.WithField(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds a struct of fields to the log entry. All it does is call `WithField` for
|
|
||||||
// each `Field`.
|
|
||||||
func (logger *Logger) WithFields(fields Fields) *Entry {
|
|
||||||
entry := logger.newEntry()
|
|
||||||
defer logger.releaseEntry(entry)
|
|
||||||
return entry.WithFields(fields)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add an error as single field to the log entry. All it does is call
|
|
||||||
// `WithError` for the given `error`.
|
|
||||||
func (logger *Logger) WithError(err error) *Entry {
|
|
||||||
entry := logger.newEntry()
|
|
||||||
defer logger.releaseEntry(entry)
|
|
||||||
return entry.WithError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a context to the log entry.
|
|
||||||
func (logger *Logger) WithContext(ctx context.Context) *Entry {
|
|
||||||
entry := logger.newEntry()
|
|
||||||
defer logger.releaseEntry(entry)
|
|
||||||
return entry.WithContext(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overrides the time of the log entry.
|
|
||||||
func (logger *Logger) WithTime(t time.Time) *Entry {
|
|
||||||
entry := logger.newEntry()
|
|
||||||
defer logger.releaseEntry(entry)
|
|
||||||
return entry.WithTime(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Logf(level Level, format string, args ...interface{}) {
|
|
||||||
if logger.IsLevelEnabled(level) {
|
|
||||||
entry := logger.newEntry()
|
|
||||||
entry.Logf(level, format, args...)
|
|
||||||
logger.releaseEntry(entry)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Tracef(format string, args ...interface{}) {
|
|
||||||
logger.Logf(TraceLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Debugf(format string, args ...interface{}) {
|
|
||||||
logger.Logf(DebugLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Infof(format string, args ...interface{}) {
|
|
||||||
logger.Logf(InfoLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Printf(format string, args ...interface{}) {
|
|
||||||
entry := logger.newEntry()
|
|
||||||
entry.Printf(format, args...)
|
|
||||||
logger.releaseEntry(entry)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Warnf(format string, args ...interface{}) {
|
|
||||||
logger.Logf(WarnLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Warningf(format string, args ...interface{}) {
|
|
||||||
logger.Warnf(format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Errorf(format string, args ...interface{}) {
|
|
||||||
logger.Logf(ErrorLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Fatalf(format string, args ...interface{}) {
|
|
||||||
logger.Logf(FatalLevel, format, args...)
|
|
||||||
logger.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Panicf(format string, args ...interface{}) {
|
|
||||||
logger.Logf(PanicLevel, format, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Log(level Level, args ...interface{}) {
|
|
||||||
if logger.IsLevelEnabled(level) {
|
|
||||||
entry := logger.newEntry()
|
|
||||||
entry.Log(level, args...)
|
|
||||||
logger.releaseEntry(entry)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) LogFn(level Level, fn LogFunction) {
|
|
||||||
if logger.IsLevelEnabled(level) {
|
|
||||||
entry := logger.newEntry()
|
|
||||||
entry.Log(level, fn()...)
|
|
||||||
logger.releaseEntry(entry)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Trace(args ...interface{}) {
|
|
||||||
logger.Log(TraceLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Debug(args ...interface{}) {
|
|
||||||
logger.Log(DebugLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Info(args ...interface{}) {
|
|
||||||
logger.Log(InfoLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Print(args ...interface{}) {
|
|
||||||
entry := logger.newEntry()
|
|
||||||
entry.Print(args...)
|
|
||||||
logger.releaseEntry(entry)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Warn(args ...interface{}) {
|
|
||||||
logger.Log(WarnLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Warning(args ...interface{}) {
|
|
||||||
logger.Warn(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Error(args ...interface{}) {
|
|
||||||
logger.Log(ErrorLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Fatal(args ...interface{}) {
|
|
||||||
logger.Log(FatalLevel, args...)
|
|
||||||
logger.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Panic(args ...interface{}) {
|
|
||||||
logger.Log(PanicLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) TraceFn(fn LogFunction) {
|
|
||||||
logger.LogFn(TraceLevel, fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) DebugFn(fn LogFunction) {
|
|
||||||
logger.LogFn(DebugLevel, fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) InfoFn(fn LogFunction) {
|
|
||||||
logger.LogFn(InfoLevel, fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) PrintFn(fn LogFunction) {
|
|
||||||
entry := logger.newEntry()
|
|
||||||
entry.Print(fn()...)
|
|
||||||
logger.releaseEntry(entry)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) WarnFn(fn LogFunction) {
|
|
||||||
logger.LogFn(WarnLevel, fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) WarningFn(fn LogFunction) {
|
|
||||||
logger.WarnFn(fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) ErrorFn(fn LogFunction) {
|
|
||||||
logger.LogFn(ErrorLevel, fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) FatalFn(fn LogFunction) {
|
|
||||||
logger.LogFn(FatalLevel, fn)
|
|
||||||
logger.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) PanicFn(fn LogFunction) {
|
|
||||||
logger.LogFn(PanicLevel, fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Logln(level Level, args ...interface{}) {
|
|
||||||
if logger.IsLevelEnabled(level) {
|
|
||||||
entry := logger.newEntry()
|
|
||||||
entry.Logln(level, args...)
|
|
||||||
logger.releaseEntry(entry)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Traceln(args ...interface{}) {
|
|
||||||
logger.Logln(TraceLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Debugln(args ...interface{}) {
|
|
||||||
logger.Logln(DebugLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Infoln(args ...interface{}) {
|
|
||||||
logger.Logln(InfoLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Println(args ...interface{}) {
|
|
||||||
entry := logger.newEntry()
|
|
||||||
entry.Println(args...)
|
|
||||||
logger.releaseEntry(entry)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Warnln(args ...interface{}) {
|
|
||||||
logger.Logln(WarnLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Warningln(args ...interface{}) {
|
|
||||||
logger.Warnln(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Errorln(args ...interface{}) {
|
|
||||||
logger.Logln(ErrorLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Fatalln(args ...interface{}) {
|
|
||||||
logger.Logln(FatalLevel, args...)
|
|
||||||
logger.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Panicln(args ...interface{}) {
|
|
||||||
logger.Logln(PanicLevel, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) Exit(code int) {
|
|
||||||
runHandlers()
|
|
||||||
if logger.ExitFunc == nil {
|
|
||||||
logger.ExitFunc = os.Exit
|
|
||||||
}
|
|
||||||
logger.ExitFunc(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
//When file is opened with appending mode, it's safe to
|
|
||||||
//write concurrently to a file (within 4k message on Linux).
|
|
||||||
//In these cases user can choose to disable the lock.
|
|
||||||
func (logger *Logger) SetNoLock() {
|
|
||||||
logger.mu.Disable()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) level() Level {
|
|
||||||
return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetLevel sets the logger level.
|
|
||||||
func (logger *Logger) SetLevel(level Level) {
|
|
||||||
atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetLevel returns the logger level.
|
|
||||||
func (logger *Logger) GetLevel() Level {
|
|
||||||
return logger.level()
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddHook adds a hook to the logger hooks.
|
|
||||||
func (logger *Logger) AddHook(hook Hook) {
|
|
||||||
logger.mu.Lock()
|
|
||||||
defer logger.mu.Unlock()
|
|
||||||
logger.Hooks.Add(hook)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsLevelEnabled checks if the log level of the logger is greater than the level param
|
|
||||||
func (logger *Logger) IsLevelEnabled(level Level) bool {
|
|
||||||
return logger.level() >= level
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFormatter sets the logger formatter.
|
|
||||||
func (logger *Logger) SetFormatter(formatter Formatter) {
|
|
||||||
logger.mu.Lock()
|
|
||||||
defer logger.mu.Unlock()
|
|
||||||
logger.Formatter = formatter
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetOutput sets the logger output.
|
|
||||||
func (logger *Logger) SetOutput(output io.Writer) {
|
|
||||||
logger.mu.Lock()
|
|
||||||
defer logger.mu.Unlock()
|
|
||||||
logger.Out = output
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) SetReportCaller(reportCaller bool) {
|
|
||||||
logger.mu.Lock()
|
|
||||||
defer logger.mu.Unlock()
|
|
||||||
logger.ReportCaller = reportCaller
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReplaceHooks replaces the logger hooks and returns the old ones
|
|
||||||
func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks {
|
|
||||||
logger.mu.Lock()
|
|
||||||
oldHooks := logger.Hooks
|
|
||||||
logger.Hooks = hooks
|
|
||||||
logger.mu.Unlock()
|
|
||||||
return oldHooks
|
|
||||||
}
|
|
||||||
186
vendor/github.com/sirupsen/logrus/logrus.go
generated
vendored
186
vendor/github.com/sirupsen/logrus/logrus.go
generated
vendored
@@ -1,186 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Fields type, used to pass to `WithFields`.
|
|
||||||
type Fields map[string]interface{}
|
|
||||||
|
|
||||||
// Level type
|
|
||||||
type Level uint32
|
|
||||||
|
|
||||||
// Convert the Level to a string. E.g. PanicLevel becomes "panic".
|
|
||||||
func (level Level) String() string {
|
|
||||||
if b, err := level.MarshalText(); err == nil {
|
|
||||||
return string(b)
|
|
||||||
} else {
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseLevel takes a string level and returns the Logrus log level constant.
|
|
||||||
func ParseLevel(lvl string) (Level, error) {
|
|
||||||
switch strings.ToLower(lvl) {
|
|
||||||
case "panic":
|
|
||||||
return PanicLevel, nil
|
|
||||||
case "fatal":
|
|
||||||
return FatalLevel, nil
|
|
||||||
case "error":
|
|
||||||
return ErrorLevel, nil
|
|
||||||
case "warn", "warning":
|
|
||||||
return WarnLevel, nil
|
|
||||||
case "info":
|
|
||||||
return InfoLevel, nil
|
|
||||||
case "debug":
|
|
||||||
return DebugLevel, nil
|
|
||||||
case "trace":
|
|
||||||
return TraceLevel, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var l Level
|
|
||||||
return l, fmt.Errorf("not a valid logrus Level: %q", lvl)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
|
||||||
func (level *Level) UnmarshalText(text []byte) error {
|
|
||||||
l, err := ParseLevel(string(text))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*level = l
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (level Level) MarshalText() ([]byte, error) {
|
|
||||||
switch level {
|
|
||||||
case TraceLevel:
|
|
||||||
return []byte("trace"), nil
|
|
||||||
case DebugLevel:
|
|
||||||
return []byte("debug"), nil
|
|
||||||
case InfoLevel:
|
|
||||||
return []byte("info"), nil
|
|
||||||
case WarnLevel:
|
|
||||||
return []byte("warning"), nil
|
|
||||||
case ErrorLevel:
|
|
||||||
return []byte("error"), nil
|
|
||||||
case FatalLevel:
|
|
||||||
return []byte("fatal"), nil
|
|
||||||
case PanicLevel:
|
|
||||||
return []byte("panic"), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, fmt.Errorf("not a valid logrus level %d", level)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A constant exposing all logging levels
|
|
||||||
var AllLevels = []Level{
|
|
||||||
PanicLevel,
|
|
||||||
FatalLevel,
|
|
||||||
ErrorLevel,
|
|
||||||
WarnLevel,
|
|
||||||
InfoLevel,
|
|
||||||
DebugLevel,
|
|
||||||
TraceLevel,
|
|
||||||
}
|
|
||||||
|
|
||||||
// These are the different logging levels. You can set the logging level to log
|
|
||||||
// on your instance of logger, obtained with `logrus.New()`.
|
|
||||||
const (
|
|
||||||
// PanicLevel level, highest level of severity. Logs and then calls panic with the
|
|
||||||
// message passed to Debug, Info, ...
|
|
||||||
PanicLevel Level = iota
|
|
||||||
// FatalLevel level. Logs and then calls `logger.Exit(1)`. It will exit even if the
|
|
||||||
// logging level is set to Panic.
|
|
||||||
FatalLevel
|
|
||||||
// ErrorLevel level. Logs. Used for errors that should definitely be noted.
|
|
||||||
// Commonly used for hooks to send errors to an error tracking service.
|
|
||||||
ErrorLevel
|
|
||||||
// WarnLevel level. Non-critical entries that deserve eyes.
|
|
||||||
WarnLevel
|
|
||||||
// InfoLevel level. General operational entries about what's going on inside the
|
|
||||||
// application.
|
|
||||||
InfoLevel
|
|
||||||
// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
|
|
||||||
DebugLevel
|
|
||||||
// TraceLevel level. Designates finer-grained informational events than the Debug.
|
|
||||||
TraceLevel
|
|
||||||
)
|
|
||||||
|
|
||||||
// Won't compile if StdLogger can't be realized by a log.Logger
|
|
||||||
var (
|
|
||||||
_ StdLogger = &log.Logger{}
|
|
||||||
_ StdLogger = &Entry{}
|
|
||||||
_ StdLogger = &Logger{}
|
|
||||||
)
|
|
||||||
|
|
||||||
// StdLogger is what your logrus-enabled library should take, that way
|
|
||||||
// it'll accept a stdlib logger and a logrus logger. There's no standard
|
|
||||||
// interface, this is the closest we get, unfortunately.
|
|
||||||
type StdLogger interface {
|
|
||||||
Print(...interface{})
|
|
||||||
Printf(string, ...interface{})
|
|
||||||
Println(...interface{})
|
|
||||||
|
|
||||||
Fatal(...interface{})
|
|
||||||
Fatalf(string, ...interface{})
|
|
||||||
Fatalln(...interface{})
|
|
||||||
|
|
||||||
Panic(...interface{})
|
|
||||||
Panicf(string, ...interface{})
|
|
||||||
Panicln(...interface{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// The FieldLogger interface generalizes the Entry and Logger types
|
|
||||||
type FieldLogger interface {
|
|
||||||
WithField(key string, value interface{}) *Entry
|
|
||||||
WithFields(fields Fields) *Entry
|
|
||||||
WithError(err error) *Entry
|
|
||||||
|
|
||||||
Debugf(format string, args ...interface{})
|
|
||||||
Infof(format string, args ...interface{})
|
|
||||||
Printf(format string, args ...interface{})
|
|
||||||
Warnf(format string, args ...interface{})
|
|
||||||
Warningf(format string, args ...interface{})
|
|
||||||
Errorf(format string, args ...interface{})
|
|
||||||
Fatalf(format string, args ...interface{})
|
|
||||||
Panicf(format string, args ...interface{})
|
|
||||||
|
|
||||||
Debug(args ...interface{})
|
|
||||||
Info(args ...interface{})
|
|
||||||
Print(args ...interface{})
|
|
||||||
Warn(args ...interface{})
|
|
||||||
Warning(args ...interface{})
|
|
||||||
Error(args ...interface{})
|
|
||||||
Fatal(args ...interface{})
|
|
||||||
Panic(args ...interface{})
|
|
||||||
|
|
||||||
Debugln(args ...interface{})
|
|
||||||
Infoln(args ...interface{})
|
|
||||||
Println(args ...interface{})
|
|
||||||
Warnln(args ...interface{})
|
|
||||||
Warningln(args ...interface{})
|
|
||||||
Errorln(args ...interface{})
|
|
||||||
Fatalln(args ...interface{})
|
|
||||||
Panicln(args ...interface{})
|
|
||||||
|
|
||||||
// IsDebugEnabled() bool
|
|
||||||
// IsInfoEnabled() bool
|
|
||||||
// IsWarnEnabled() bool
|
|
||||||
// IsErrorEnabled() bool
|
|
||||||
// IsFatalEnabled() bool
|
|
||||||
// IsPanicEnabled() bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ext1FieldLogger (the first extension to FieldLogger) is superfluous, it is
|
|
||||||
// here for consistancy. Do not use. Use Logger or Entry instead.
|
|
||||||
type Ext1FieldLogger interface {
|
|
||||||
FieldLogger
|
|
||||||
Tracef(format string, args ...interface{})
|
|
||||||
Trace(args ...interface{})
|
|
||||||
Traceln(args ...interface{})
|
|
||||||
}
|
|
||||||
11
vendor/github.com/sirupsen/logrus/terminal_check_appengine.go
generated
vendored
11
vendor/github.com/sirupsen/logrus/terminal_check_appengine.go
generated
vendored
@@ -1,11 +0,0 @@
|
|||||||
// +build appengine
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
func checkIfTerminal(w io.Writer) bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
13
vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
generated
vendored
13
vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
generated
vendored
@@ -1,13 +0,0 @@
|
|||||||
// +build darwin dragonfly freebsd netbsd openbsd
|
|
||||||
// +build !js
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import "golang.org/x/sys/unix"
|
|
||||||
|
|
||||||
const ioctlReadTermios = unix.TIOCGETA
|
|
||||||
|
|
||||||
func isTerminal(fd int) bool {
|
|
||||||
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
7
vendor/github.com/sirupsen/logrus/terminal_check_js.go
generated
vendored
7
vendor/github.com/sirupsen/logrus/terminal_check_js.go
generated
vendored
@@ -1,7 +0,0 @@
|
|||||||
// +build js
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
func isTerminal(fd int) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
11
vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go
generated
vendored
11
vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go
generated
vendored
@@ -1,11 +0,0 @@
|
|||||||
// +build js nacl plan9
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
func checkIfTerminal(w io.Writer) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
17
vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
generated
vendored
17
vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
generated
vendored
@@ -1,17 +0,0 @@
|
|||||||
// +build !appengine,!js,!windows,!nacl,!plan9
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
func checkIfTerminal(w io.Writer) bool {
|
|
||||||
switch v := w.(type) {
|
|
||||||
case *os.File:
|
|
||||||
return isTerminal(int(v.Fd()))
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
11
vendor/github.com/sirupsen/logrus/terminal_check_solaris.go
generated
vendored
11
vendor/github.com/sirupsen/logrus/terminal_check_solaris.go
generated
vendored
@@ -1,11 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
|
||||||
func isTerminal(fd int) bool {
|
|
||||||
_, err := unix.IoctlGetTermio(fd, unix.TCGETA)
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
13
vendor/github.com/sirupsen/logrus/terminal_check_unix.go
generated
vendored
13
vendor/github.com/sirupsen/logrus/terminal_check_unix.go
generated
vendored
@@ -1,13 +0,0 @@
|
|||||||
// +build linux aix zos
|
|
||||||
// +build !js
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import "golang.org/x/sys/unix"
|
|
||||||
|
|
||||||
const ioctlReadTermios = unix.TCGETS
|
|
||||||
|
|
||||||
func isTerminal(fd int) bool {
|
|
||||||
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
27
vendor/github.com/sirupsen/logrus/terminal_check_windows.go
generated
vendored
27
vendor/github.com/sirupsen/logrus/terminal_check_windows.go
generated
vendored
@@ -1,27 +0,0 @@
|
|||||||
// +build !appengine,!js,windows
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"golang.org/x/sys/windows"
|
|
||||||
)
|
|
||||||
|
|
||||||
func checkIfTerminal(w io.Writer) bool {
|
|
||||||
switch v := w.(type) {
|
|
||||||
case *os.File:
|
|
||||||
handle := windows.Handle(v.Fd())
|
|
||||||
var mode uint32
|
|
||||||
if err := windows.GetConsoleMode(handle, &mode); err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
mode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
|
||||||
if err := windows.SetConsoleMode(handle, mode); err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
339
vendor/github.com/sirupsen/logrus/text_formatter.go
generated
vendored
339
vendor/github.com/sirupsen/logrus/text_formatter.go
generated
vendored
@@ -1,339 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"sort"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
"unicode/utf8"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
red = 31
|
|
||||||
yellow = 33
|
|
||||||
blue = 36
|
|
||||||
gray = 37
|
|
||||||
)
|
|
||||||
|
|
||||||
var baseTimestamp time.Time
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
baseTimestamp = time.Now()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TextFormatter formats logs into text
|
|
||||||
type TextFormatter struct {
|
|
||||||
// Set to true to bypass checking for a TTY before outputting colors.
|
|
||||||
ForceColors bool
|
|
||||||
|
|
||||||
// Force disabling colors.
|
|
||||||
DisableColors bool
|
|
||||||
|
|
||||||
// Force quoting of all values
|
|
||||||
ForceQuote bool
|
|
||||||
|
|
||||||
// DisableQuote disables quoting for all values.
|
|
||||||
// DisableQuote will have a lower priority than ForceQuote.
|
|
||||||
// If both of them are set to true, quote will be forced on all values.
|
|
||||||
DisableQuote bool
|
|
||||||
|
|
||||||
// Override coloring based on CLICOLOR and CLICOLOR_FORCE. - https://bixense.com/clicolors/
|
|
||||||
EnvironmentOverrideColors bool
|
|
||||||
|
|
||||||
// Disable timestamp logging. useful when output is redirected to logging
|
|
||||||
// system that already adds timestamps.
|
|
||||||
DisableTimestamp bool
|
|
||||||
|
|
||||||
// Enable logging the full timestamp when a TTY is attached instead of just
|
|
||||||
// the time passed since beginning of execution.
|
|
||||||
FullTimestamp bool
|
|
||||||
|
|
||||||
// TimestampFormat to use for display when a full timestamp is printed.
|
|
||||||
// The format to use is the same than for time.Format or time.Parse from the standard
|
|
||||||
// library.
|
|
||||||
// The standard Library already provides a set of predefined format.
|
|
||||||
TimestampFormat string
|
|
||||||
|
|
||||||
// The fields are sorted by default for a consistent output. For applications
|
|
||||||
// that log extremely frequently and don't use the JSON formatter this may not
|
|
||||||
// be desired.
|
|
||||||
DisableSorting bool
|
|
||||||
|
|
||||||
// The keys sorting function, when uninitialized it uses sort.Strings.
|
|
||||||
SortingFunc func([]string)
|
|
||||||
|
|
||||||
// Disables the truncation of the level text to 4 characters.
|
|
||||||
DisableLevelTruncation bool
|
|
||||||
|
|
||||||
// PadLevelText Adds padding the level text so that all the levels output at the same length
|
|
||||||
// PadLevelText is a superset of the DisableLevelTruncation option
|
|
||||||
PadLevelText bool
|
|
||||||
|
|
||||||
// QuoteEmptyFields will wrap empty fields in quotes if true
|
|
||||||
QuoteEmptyFields bool
|
|
||||||
|
|
||||||
// Whether the logger's out is to a terminal
|
|
||||||
isTerminal bool
|
|
||||||
|
|
||||||
// FieldMap allows users to customize the names of keys for default fields.
|
|
||||||
// As an example:
|
|
||||||
// formatter := &TextFormatter{
|
|
||||||
// FieldMap: FieldMap{
|
|
||||||
// FieldKeyTime: "@timestamp",
|
|
||||||
// FieldKeyLevel: "@level",
|
|
||||||
// FieldKeyMsg: "@message"}}
|
|
||||||
FieldMap FieldMap
|
|
||||||
|
|
||||||
// CallerPrettyfier can be set by the user to modify the content
|
|
||||||
// of the function and file keys in the data when ReportCaller is
|
|
||||||
// activated. If any of the returned value is the empty string the
|
|
||||||
// corresponding key will be removed from fields.
|
|
||||||
CallerPrettyfier func(*runtime.Frame) (function string, file string)
|
|
||||||
|
|
||||||
terminalInitOnce sync.Once
|
|
||||||
|
|
||||||
// The max length of the level text, generated dynamically on init
|
|
||||||
levelTextMaxLength int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *TextFormatter) init(entry *Entry) {
|
|
||||||
if entry.Logger != nil {
|
|
||||||
f.isTerminal = checkIfTerminal(entry.Logger.Out)
|
|
||||||
}
|
|
||||||
// Get the max length of the level text
|
|
||||||
for _, level := range AllLevels {
|
|
||||||
levelTextLength := utf8.RuneCount([]byte(level.String()))
|
|
||||||
if levelTextLength > f.levelTextMaxLength {
|
|
||||||
f.levelTextMaxLength = levelTextLength
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *TextFormatter) isColored() bool {
|
|
||||||
isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != "windows"))
|
|
||||||
|
|
||||||
if f.EnvironmentOverrideColors {
|
|
||||||
switch force, ok := os.LookupEnv("CLICOLOR_FORCE"); {
|
|
||||||
case ok && force != "0":
|
|
||||||
isColored = true
|
|
||||||
case ok && force == "0", os.Getenv("CLICOLOR") == "0":
|
|
||||||
isColored = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return isColored && !f.DisableColors
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format renders a single log entry
|
|
||||||
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
|
||||||
data := make(Fields)
|
|
||||||
for k, v := range entry.Data {
|
|
||||||
data[k] = v
|
|
||||||
}
|
|
||||||
prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
|
|
||||||
keys := make([]string, 0, len(data))
|
|
||||||
for k := range data {
|
|
||||||
keys = append(keys, k)
|
|
||||||
}
|
|
||||||
|
|
||||||
var funcVal, fileVal string
|
|
||||||
|
|
||||||
fixedKeys := make([]string, 0, 4+len(data))
|
|
||||||
if !f.DisableTimestamp {
|
|
||||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime))
|
|
||||||
}
|
|
||||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLevel))
|
|
||||||
if entry.Message != "" {
|
|
||||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyMsg))
|
|
||||||
}
|
|
||||||
if entry.err != "" {
|
|
||||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLogrusError))
|
|
||||||
}
|
|
||||||
if entry.HasCaller() {
|
|
||||||
if f.CallerPrettyfier != nil {
|
|
||||||
funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
|
|
||||||
} else {
|
|
||||||
funcVal = entry.Caller.Function
|
|
||||||
fileVal = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
|
|
||||||
}
|
|
||||||
|
|
||||||
if funcVal != "" {
|
|
||||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyFunc))
|
|
||||||
}
|
|
||||||
if fileVal != "" {
|
|
||||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyFile))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !f.DisableSorting {
|
|
||||||
if f.SortingFunc == nil {
|
|
||||||
sort.Strings(keys)
|
|
||||||
fixedKeys = append(fixedKeys, keys...)
|
|
||||||
} else {
|
|
||||||
if !f.isColored() {
|
|
||||||
fixedKeys = append(fixedKeys, keys...)
|
|
||||||
f.SortingFunc(fixedKeys)
|
|
||||||
} else {
|
|
||||||
f.SortingFunc(keys)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fixedKeys = append(fixedKeys, keys...)
|
|
||||||
}
|
|
||||||
|
|
||||||
var b *bytes.Buffer
|
|
||||||
if entry.Buffer != nil {
|
|
||||||
b = entry.Buffer
|
|
||||||
} else {
|
|
||||||
b = &bytes.Buffer{}
|
|
||||||
}
|
|
||||||
|
|
||||||
f.terminalInitOnce.Do(func() { f.init(entry) })
|
|
||||||
|
|
||||||
timestampFormat := f.TimestampFormat
|
|
||||||
if timestampFormat == "" {
|
|
||||||
timestampFormat = defaultTimestampFormat
|
|
||||||
}
|
|
||||||
if f.isColored() {
|
|
||||||
f.printColored(b, entry, keys, data, timestampFormat)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
for _, key := range fixedKeys {
|
|
||||||
var value interface{}
|
|
||||||
switch {
|
|
||||||
case key == f.FieldMap.resolve(FieldKeyTime):
|
|
||||||
value = entry.Time.Format(timestampFormat)
|
|
||||||
case key == f.FieldMap.resolve(FieldKeyLevel):
|
|
||||||
value = entry.Level.String()
|
|
||||||
case key == f.FieldMap.resolve(FieldKeyMsg):
|
|
||||||
value = entry.Message
|
|
||||||
case key == f.FieldMap.resolve(FieldKeyLogrusError):
|
|
||||||
value = entry.err
|
|
||||||
case key == f.FieldMap.resolve(FieldKeyFunc) && entry.HasCaller():
|
|
||||||
value = funcVal
|
|
||||||
case key == f.FieldMap.resolve(FieldKeyFile) && entry.HasCaller():
|
|
||||||
value = fileVal
|
|
||||||
default:
|
|
||||||
value = data[key]
|
|
||||||
}
|
|
||||||
f.appendKeyValue(b, key, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
b.WriteByte('\n')
|
|
||||||
return b.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, data Fields, timestampFormat string) {
|
|
||||||
var levelColor int
|
|
||||||
switch entry.Level {
|
|
||||||
case DebugLevel, TraceLevel:
|
|
||||||
levelColor = gray
|
|
||||||
case WarnLevel:
|
|
||||||
levelColor = yellow
|
|
||||||
case ErrorLevel, FatalLevel, PanicLevel:
|
|
||||||
levelColor = red
|
|
||||||
case InfoLevel:
|
|
||||||
levelColor = blue
|
|
||||||
default:
|
|
||||||
levelColor = blue
|
|
||||||
}
|
|
||||||
|
|
||||||
levelText := strings.ToUpper(entry.Level.String())
|
|
||||||
if !f.DisableLevelTruncation && !f.PadLevelText {
|
|
||||||
levelText = levelText[0:4]
|
|
||||||
}
|
|
||||||
if f.PadLevelText {
|
|
||||||
// Generates the format string used in the next line, for example "%-6s" or "%-7s".
|
|
||||||
// Based on the max level text length.
|
|
||||||
formatString := "%-" + strconv.Itoa(f.levelTextMaxLength) + "s"
|
|
||||||
// Formats the level text by appending spaces up to the max length, for example:
|
|
||||||
// - "INFO "
|
|
||||||
// - "WARNING"
|
|
||||||
levelText = fmt.Sprintf(formatString, levelText)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove a single newline if it already exists in the message to keep
|
|
||||||
// the behavior of logrus text_formatter the same as the stdlib log package
|
|
||||||
entry.Message = strings.TrimSuffix(entry.Message, "\n")
|
|
||||||
|
|
||||||
caller := ""
|
|
||||||
if entry.HasCaller() {
|
|
||||||
funcVal := fmt.Sprintf("%s()", entry.Caller.Function)
|
|
||||||
fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
|
|
||||||
|
|
||||||
if f.CallerPrettyfier != nil {
|
|
||||||
funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
|
|
||||||
}
|
|
||||||
|
|
||||||
if fileVal == "" {
|
|
||||||
caller = funcVal
|
|
||||||
} else if funcVal == "" {
|
|
||||||
caller = fileVal
|
|
||||||
} else {
|
|
||||||
caller = fileVal + " " + funcVal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case f.DisableTimestamp:
|
|
||||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m%s %-44s ", levelColor, levelText, caller, entry.Message)
|
|
||||||
case !f.FullTimestamp:
|
|
||||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d]%s %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), caller, entry.Message)
|
|
||||||
default:
|
|
||||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message)
|
|
||||||
}
|
|
||||||
for _, k := range keys {
|
|
||||||
v := data[k]
|
|
||||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
|
|
||||||
f.appendValue(b, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *TextFormatter) needsQuoting(text string) bool {
|
|
||||||
if f.ForceQuote {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if f.QuoteEmptyFields && len(text) == 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if f.DisableQuote {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, ch := range text {
|
|
||||||
if !((ch >= 'a' && ch <= 'z') ||
|
|
||||||
(ch >= 'A' && ch <= 'Z') ||
|
|
||||||
(ch >= '0' && ch <= '9') ||
|
|
||||||
ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
|
||||||
if b.Len() > 0 {
|
|
||||||
b.WriteByte(' ')
|
|
||||||
}
|
|
||||||
b.WriteString(key)
|
|
||||||
b.WriteByte('=')
|
|
||||||
f.appendValue(b, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
|
||||||
stringVal, ok := value.(string)
|
|
||||||
if !ok {
|
|
||||||
stringVal = fmt.Sprint(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !f.needsQuoting(stringVal) {
|
|
||||||
b.WriteString(stringVal)
|
|
||||||
} else {
|
|
||||||
b.WriteString(fmt.Sprintf("%q", stringVal))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
70
vendor/github.com/sirupsen/logrus/writer.go
generated
vendored
70
vendor/github.com/sirupsen/logrus/writer.go
generated
vendored
@@ -1,70 +0,0 @@
|
|||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"io"
|
|
||||||
"runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Writer at INFO level. See WriterLevel for details.
|
|
||||||
func (logger *Logger) Writer() *io.PipeWriter {
|
|
||||||
return logger.WriterLevel(InfoLevel)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriterLevel returns an io.Writer that can be used to write arbitrary text to
|
|
||||||
// the logger at the given log level. Each line written to the writer will be
|
|
||||||
// printed in the usual way using formatters and hooks. The writer is part of an
|
|
||||||
// io.Pipe and it is the callers responsibility to close the writer when done.
|
|
||||||
// This can be used to override the standard library logger easily.
|
|
||||||
func (logger *Logger) WriterLevel(level Level) *io.PipeWriter {
|
|
||||||
return NewEntry(logger).WriterLevel(level)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) Writer() *io.PipeWriter {
|
|
||||||
return entry.WriterLevel(InfoLevel)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
|
|
||||||
reader, writer := io.Pipe()
|
|
||||||
|
|
||||||
var printFunc func(args ...interface{})
|
|
||||||
|
|
||||||
switch level {
|
|
||||||
case TraceLevel:
|
|
||||||
printFunc = entry.Trace
|
|
||||||
case DebugLevel:
|
|
||||||
printFunc = entry.Debug
|
|
||||||
case InfoLevel:
|
|
||||||
printFunc = entry.Info
|
|
||||||
case WarnLevel:
|
|
||||||
printFunc = entry.Warn
|
|
||||||
case ErrorLevel:
|
|
||||||
printFunc = entry.Error
|
|
||||||
case FatalLevel:
|
|
||||||
printFunc = entry.Fatal
|
|
||||||
case PanicLevel:
|
|
||||||
printFunc = entry.Panic
|
|
||||||
default:
|
|
||||||
printFunc = entry.Print
|
|
||||||
}
|
|
||||||
|
|
||||||
go entry.writerScanner(reader, printFunc)
|
|
||||||
runtime.SetFinalizer(writer, writerFinalizer)
|
|
||||||
|
|
||||||
return writer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) {
|
|
||||||
scanner := bufio.NewScanner(reader)
|
|
||||||
for scanner.Scan() {
|
|
||||||
printFunc(scanner.Text())
|
|
||||||
}
|
|
||||||
if err := scanner.Err(); err != nil {
|
|
||||||
entry.Errorf("Error while reading from Writer: %s", err)
|
|
||||||
}
|
|
||||||
reader.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func writerFinalizer(writer *io.PipeWriter) {
|
|
||||||
writer.Close()
|
|
||||||
}
|
|
||||||
3
vendor/golang.org/x/sys/AUTHORS
generated
vendored
3
vendor/golang.org/x/sys/AUTHORS
generated
vendored
@@ -1,3 +0,0 @@
|
|||||||
# This source code refers to The Go Authors for copyright purposes.
|
|
||||||
# The master list of authors is in the main Go distribution,
|
|
||||||
# visible at http://tip.golang.org/AUTHORS.
|
|
||||||
3
vendor/golang.org/x/sys/CONTRIBUTORS
generated
vendored
3
vendor/golang.org/x/sys/CONTRIBUTORS
generated
vendored
@@ -1,3 +0,0 @@
|
|||||||
# This source code was written by the Go contributors.
|
|
||||||
# The master list of contributors is in the main Go distribution,
|
|
||||||
# visible at http://tip.golang.org/CONTRIBUTORS.
|
|
||||||
27
vendor/golang.org/x/sys/LICENSE
generated
vendored
27
vendor/golang.org/x/sys/LICENSE
generated
vendored
@@ -1,27 +0,0 @@
|
|||||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
* Neither the name of Google Inc. nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
22
vendor/golang.org/x/sys/PATENTS
generated
vendored
22
vendor/golang.org/x/sys/PATENTS
generated
vendored
@@ -1,22 +0,0 @@
|
|||||||
Additional IP Rights Grant (Patents)
|
|
||||||
|
|
||||||
"This implementation" means the copyrightable works distributed by
|
|
||||||
Google as part of the Go project.
|
|
||||||
|
|
||||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
|
||||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
|
||||||
patent license to make, have made, use, offer to sell, sell, import,
|
|
||||||
transfer and otherwise run, modify and propagate the contents of this
|
|
||||||
implementation of Go, where such license applies only to those patent
|
|
||||||
claims, both currently owned or controlled by Google and acquired in
|
|
||||||
the future, licensable by Google that are necessarily infringed by this
|
|
||||||
implementation of Go. This grant does not include claims that would be
|
|
||||||
infringed only as a consequence of further modification of this
|
|
||||||
implementation. If you or your agent or exclusive licensee institute or
|
|
||||||
order or agree to the institution of patent litigation against any
|
|
||||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
|
||||||
that this implementation of Go or any code incorporated within this
|
|
||||||
implementation of Go constitutes direct or contributory patent
|
|
||||||
infringement, or inducement of patent infringement, then any patent
|
|
||||||
rights granted to you under this License for this implementation of Go
|
|
||||||
shall terminate as of the date such litigation is filed.
|
|
||||||
30
vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go
generated
vendored
30
vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go
generated
vendored
@@ -1,30 +0,0 @@
|
|||||||
// Copyright 2020 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 unsafeheader contains header declarations for the Go runtime's
|
|
||||||
// slice and string implementations.
|
|
||||||
//
|
|
||||||
// This package allows x/sys to use types equivalent to
|
|
||||||
// reflect.SliceHeader and reflect.StringHeader without introducing
|
|
||||||
// a dependency on the (relatively heavy) "reflect" package.
|
|
||||||
package unsafeheader
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Slice is the runtime representation of a slice.
|
|
||||||
// It cannot be used safely or portably and its representation may change in a later release.
|
|
||||||
type Slice struct {
|
|
||||||
Data unsafe.Pointer
|
|
||||||
Len int
|
|
||||||
Cap int
|
|
||||||
}
|
|
||||||
|
|
||||||
// String is the runtime representation of a string.
|
|
||||||
// It cannot be used safely or portably and its representation may change in a later release.
|
|
||||||
type String struct {
|
|
||||||
Data unsafe.Pointer
|
|
||||||
Len int
|
|
||||||
}
|
|
||||||
2
vendor/golang.org/x/sys/unix/.gitignore
generated
vendored
2
vendor/golang.org/x/sys/unix/.gitignore
generated
vendored
@@ -1,2 +0,0 @@
|
|||||||
_obj/
|
|
||||||
unix.test
|
|
||||||
184
vendor/golang.org/x/sys/unix/README.md
generated
vendored
184
vendor/golang.org/x/sys/unix/README.md
generated
vendored
@@ -1,184 +0,0 @@
|
|||||||
# Building `sys/unix`
|
|
||||||
|
|
||||||
The sys/unix package provides access to the raw system call interface of the
|
|
||||||
underlying operating system. See: https://godoc.org/golang.org/x/sys/unix
|
|
||||||
|
|
||||||
Porting Go to a new architecture/OS combination or adding syscalls, types, or
|
|
||||||
constants to an existing architecture/OS pair requires some manual effort;
|
|
||||||
however, there are tools that automate much of the process.
|
|
||||||
|
|
||||||
## Build Systems
|
|
||||||
|
|
||||||
There are currently two ways we generate the necessary files. We are currently
|
|
||||||
migrating the build system to use containers so the builds are reproducible.
|
|
||||||
This is being done on an OS-by-OS basis. Please update this documentation as
|
|
||||||
components of the build system change.
|
|
||||||
|
|
||||||
### Old Build System (currently for `GOOS != "linux"`)
|
|
||||||
|
|
||||||
The old build system generates the Go files based on the C header files
|
|
||||||
present on your system. This means that files
|
|
||||||
for a given GOOS/GOARCH pair must be generated on a system with that OS and
|
|
||||||
architecture. This also means that the generated code can differ from system
|
|
||||||
to system, based on differences in the header files.
|
|
||||||
|
|
||||||
To avoid this, if you are using the old build system, only generate the Go
|
|
||||||
files on an installation with unmodified header files. It is also important to
|
|
||||||
keep track of which version of the OS the files were generated from (ex.
|
|
||||||
Darwin 14 vs Darwin 15). This makes it easier to track the progress of changes
|
|
||||||
and have each OS upgrade correspond to a single change.
|
|
||||||
|
|
||||||
To build the files for your current OS and architecture, make sure GOOS and
|
|
||||||
GOARCH are set correctly and run `mkall.sh`. This will generate the files for
|
|
||||||
your specific system. Running `mkall.sh -n` shows the commands that will be run.
|
|
||||||
|
|
||||||
Requirements: bash, go
|
|
||||||
|
|
||||||
### New Build System (currently for `GOOS == "linux"`)
|
|
||||||
|
|
||||||
The new build system uses a Docker container to generate the go files directly
|
|
||||||
from source checkouts of the kernel and various system libraries. This means
|
|
||||||
that on any platform that supports Docker, all the files using the new build
|
|
||||||
system can be generated at once, and generated files will not change based on
|
|
||||||
what the person running the scripts has installed on their computer.
|
|
||||||
|
|
||||||
The OS specific files for the new build system are located in the `${GOOS}`
|
|
||||||
directory, and the build is coordinated by the `${GOOS}/mkall.go` program. When
|
|
||||||
the kernel or system library updates, modify the Dockerfile at
|
|
||||||
`${GOOS}/Dockerfile` to checkout the new release of the source.
|
|
||||||
|
|
||||||
To build all the files under the new build system, you must be on an amd64/Linux
|
|
||||||
system and have your GOOS and GOARCH set accordingly. Running `mkall.sh` will
|
|
||||||
then generate all of the files for all of the GOOS/GOARCH pairs in the new build
|
|
||||||
system. Running `mkall.sh -n` shows the commands that will be run.
|
|
||||||
|
|
||||||
Requirements: bash, go, docker
|
|
||||||
|
|
||||||
## Component files
|
|
||||||
|
|
||||||
This section describes the various files used in the code generation process.
|
|
||||||
It also contains instructions on how to modify these files to add a new
|
|
||||||
architecture/OS or to add additional syscalls, types, or constants. Note that
|
|
||||||
if you are using the new build system, the scripts/programs cannot be called normally.
|
|
||||||
They must be called from within the docker container.
|
|
||||||
|
|
||||||
### asm files
|
|
||||||
|
|
||||||
The hand-written assembly file at `asm_${GOOS}_${GOARCH}.s` implements system
|
|
||||||
call dispatch. There are three entry points:
|
|
||||||
```
|
|
||||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
|
||||||
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
|
|
||||||
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
|
||||||
```
|
|
||||||
The first and second are the standard ones; they differ only in how many
|
|
||||||
arguments can be passed to the kernel. The third is for low-level use by the
|
|
||||||
ForkExec wrapper. Unlike the first two, it does not call into the scheduler to
|
|
||||||
let it know that a system call is running.
|
|
||||||
|
|
||||||
When porting Go to a new architecture/OS, this file must be implemented for
|
|
||||||
each GOOS/GOARCH pair.
|
|
||||||
|
|
||||||
### mksysnum
|
|
||||||
|
|
||||||
Mksysnum is a Go program located at `${GOOS}/mksysnum.go` (or `mksysnum_${GOOS}.go`
|
|
||||||
for the old system). This program takes in a list of header files containing the
|
|
||||||
syscall number declarations and parses them to produce the corresponding list of
|
|
||||||
Go numeric constants. See `zsysnum_${GOOS}_${GOARCH}.go` for the generated
|
|
||||||
constants.
|
|
||||||
|
|
||||||
Adding new syscall numbers is mostly done by running the build on a sufficiently
|
|
||||||
new installation of the target OS (or updating the source checkouts for the
|
|
||||||
new build system). However, depending on the OS, you may need to update the
|
|
||||||
parsing in mksysnum.
|
|
||||||
|
|
||||||
### mksyscall.go
|
|
||||||
|
|
||||||
The `syscall.go`, `syscall_${GOOS}.go`, `syscall_${GOOS}_${GOARCH}.go` are
|
|
||||||
hand-written Go files which implement system calls (for unix, the specific OS,
|
|
||||||
or the specific OS/Architecture pair respectively) that need special handling
|
|
||||||
and list `//sys` comments giving prototypes for ones that can be generated.
|
|
||||||
|
|
||||||
The mksyscall.go program takes the `//sys` and `//sysnb` comments and converts
|
|
||||||
them into syscalls. This requires the name of the prototype in the comment to
|
|
||||||
match a syscall number in the `zsysnum_${GOOS}_${GOARCH}.go` file. The function
|
|
||||||
prototype can be exported (capitalized) or not.
|
|
||||||
|
|
||||||
Adding a new syscall often just requires adding a new `//sys` function prototype
|
|
||||||
with the desired arguments and a capitalized name so it is exported. However, if
|
|
||||||
you want the interface to the syscall to be different, often one will make an
|
|
||||||
unexported `//sys` prototype, and then write a custom wrapper in
|
|
||||||
`syscall_${GOOS}.go`.
|
|
||||||
|
|
||||||
### types files
|
|
||||||
|
|
||||||
For each OS, there is a hand-written Go file at `${GOOS}/types.go` (or
|
|
||||||
`types_${GOOS}.go` on the old system). This file includes standard C headers and
|
|
||||||
creates Go type aliases to the corresponding C types. The file is then fed
|
|
||||||
through godef to get the Go compatible definitions. Finally, the generated code
|
|
||||||
is fed though mkpost.go to format the code correctly and remove any hidden or
|
|
||||||
private identifiers. This cleaned-up code is written to
|
|
||||||
`ztypes_${GOOS}_${GOARCH}.go`.
|
|
||||||
|
|
||||||
The hardest part about preparing this file is figuring out which headers to
|
|
||||||
include and which symbols need to be `#define`d to get the actual data
|
|
||||||
structures that pass through to the kernel system calls. Some C libraries
|
|
||||||
preset alternate versions for binary compatibility and translate them on the
|
|
||||||
way in and out of system calls, but there is almost always a `#define` that can
|
|
||||||
get the real ones.
|
|
||||||
See `types_darwin.go` and `linux/types.go` for examples.
|
|
||||||
|
|
||||||
To add a new type, add in the necessary include statement at the top of the
|
|
||||||
file (if it is not already there) and add in a type alias line. Note that if
|
|
||||||
your type is significantly different on different architectures, you may need
|
|
||||||
some `#if/#elif` macros in your include statements.
|
|
||||||
|
|
||||||
### mkerrors.sh
|
|
||||||
|
|
||||||
This script is used to generate the system's various constants. This doesn't
|
|
||||||
just include the error numbers and error strings, but also the signal numbers
|
|
||||||
and a wide variety of miscellaneous constants. The constants come from the list
|
|
||||||
of include files in the `includes_${uname}` variable. A regex then picks out
|
|
||||||
the desired `#define` statements, and generates the corresponding Go constants.
|
|
||||||
The error numbers and strings are generated from `#include <errno.h>`, and the
|
|
||||||
signal numbers and strings are generated from `#include <signal.h>`. All of
|
|
||||||
these constants are written to `zerrors_${GOOS}_${GOARCH}.go` via a C program,
|
|
||||||
`_errors.c`, which prints out all the constants.
|
|
||||||
|
|
||||||
To add a constant, add the header that includes it to the appropriate variable.
|
|
||||||
Then, edit the regex (if necessary) to match the desired constant. Avoid making
|
|
||||||
the regex too broad to avoid matching unintended constants.
|
|
||||||
|
|
||||||
### internal/mkmerge
|
|
||||||
|
|
||||||
This program is used to extract duplicate const, func, and type declarations
|
|
||||||
from the generated architecture-specific files listed below, and merge these
|
|
||||||
into a common file for each OS.
|
|
||||||
|
|
||||||
The merge is performed in the following steps:
|
|
||||||
1. Construct the set of common code that is idential in all architecture-specific files.
|
|
||||||
2. Write this common code to the merged file.
|
|
||||||
3. Remove the common code from all architecture-specific files.
|
|
||||||
|
|
||||||
|
|
||||||
## Generated files
|
|
||||||
|
|
||||||
### `zerrors_${GOOS}_${GOARCH}.go`
|
|
||||||
|
|
||||||
A file containing all of the system's generated error numbers, error strings,
|
|
||||||
signal numbers, and constants. Generated by `mkerrors.sh` (see above).
|
|
||||||
|
|
||||||
### `zsyscall_${GOOS}_${GOARCH}.go`
|
|
||||||
|
|
||||||
A file containing all the generated syscalls for a specific GOOS and GOARCH.
|
|
||||||
Generated by `mksyscall.go` (see above).
|
|
||||||
|
|
||||||
### `zsysnum_${GOOS}_${GOARCH}.go`
|
|
||||||
|
|
||||||
A list of numeric constants for all the syscall number of the specific GOOS
|
|
||||||
and GOARCH. Generated by mksysnum (see above).
|
|
||||||
|
|
||||||
### `ztypes_${GOOS}_${GOARCH}.go`
|
|
||||||
|
|
||||||
A file containing Go types for passing into (or returning from) syscalls.
|
|
||||||
Generated by godefs and the types file (see above).
|
|
||||||
86
vendor/golang.org/x/sys/unix/affinity_linux.go
generated
vendored
86
vendor/golang.org/x/sys/unix/affinity_linux.go
generated
vendored
@@ -1,86 +0,0 @@
|
|||||||
// Copyright 2018 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.
|
|
||||||
|
|
||||||
// CPU affinity functions
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/bits"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const cpuSetSize = _CPU_SETSIZE / _NCPUBITS
|
|
||||||
|
|
||||||
// CPUSet represents a CPU affinity mask.
|
|
||||||
type CPUSet [cpuSetSize]cpuMask
|
|
||||||
|
|
||||||
func schedAffinity(trap uintptr, pid int, set *CPUSet) error {
|
|
||||||
_, _, e := RawSyscall(trap, uintptr(pid), uintptr(unsafe.Sizeof(*set)), uintptr(unsafe.Pointer(set)))
|
|
||||||
if e != 0 {
|
|
||||||
return errnoErr(e)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SchedGetaffinity gets the CPU affinity mask of the thread specified by pid.
|
|
||||||
// If pid is 0 the calling thread is used.
|
|
||||||
func SchedGetaffinity(pid int, set *CPUSet) error {
|
|
||||||
return schedAffinity(SYS_SCHED_GETAFFINITY, pid, set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SchedSetaffinity sets the CPU affinity mask of the thread specified by pid.
|
|
||||||
// If pid is 0 the calling thread is used.
|
|
||||||
func SchedSetaffinity(pid int, set *CPUSet) error {
|
|
||||||
return schedAffinity(SYS_SCHED_SETAFFINITY, pid, set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zero clears the set s, so that it contains no CPUs.
|
|
||||||
func (s *CPUSet) Zero() {
|
|
||||||
for i := range s {
|
|
||||||
s[i] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func cpuBitsIndex(cpu int) int {
|
|
||||||
return cpu / _NCPUBITS
|
|
||||||
}
|
|
||||||
|
|
||||||
func cpuBitsMask(cpu int) cpuMask {
|
|
||||||
return cpuMask(1 << (uint(cpu) % _NCPUBITS))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set adds cpu to the set s.
|
|
||||||
func (s *CPUSet) Set(cpu int) {
|
|
||||||
i := cpuBitsIndex(cpu)
|
|
||||||
if i < len(s) {
|
|
||||||
s[i] |= cpuBitsMask(cpu)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear removes cpu from the set s.
|
|
||||||
func (s *CPUSet) Clear(cpu int) {
|
|
||||||
i := cpuBitsIndex(cpu)
|
|
||||||
if i < len(s) {
|
|
||||||
s[i] &^= cpuBitsMask(cpu)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsSet reports whether cpu is in the set s.
|
|
||||||
func (s *CPUSet) IsSet(cpu int) bool {
|
|
||||||
i := cpuBitsIndex(cpu)
|
|
||||||
if i < len(s) {
|
|
||||||
return s[i]&cpuBitsMask(cpu) != 0
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count returns the number of CPUs in the set s.
|
|
||||||
func (s *CPUSet) Count() int {
|
|
||||||
c := 0
|
|
||||||
for _, b := range s {
|
|
||||||
c += bits.OnesCount64(uint64(b))
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
15
vendor/golang.org/x/sys/unix/aliases.go
generated
vendored
15
vendor/golang.org/x/sys/unix/aliases.go
generated
vendored
@@ -1,15 +0,0 @@
|
|||||||
// Copyright 2018 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.
|
|
||||||
|
|
||||||
//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9
|
|
||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
|
||||||
// +build go1.9
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
type Signal = syscall.Signal
|
|
||||||
type Errno = syscall.Errno
|
|
||||||
type SysProcAttr = syscall.SysProcAttr
|
|
||||||
18
vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
generated
vendored
18
vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
generated
vendored
@@ -1,18 +0,0 @@
|
|||||||
// Copyright 2018 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.
|
|
||||||
|
|
||||||
//go:build gc
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for ppc64, AIX are implemented in runtime/syscall_aix.go
|
|
||||||
//
|
|
||||||
|
|
||||||
TEXT ·syscall6(SB),NOSPLIT,$0-88
|
|
||||||
JMP syscall·syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·rawSyscall6(SB),NOSPLIT,$0-88
|
|
||||||
JMP syscall·rawSyscall6(SB)
|
|
||||||
29
vendor/golang.org/x/sys/unix/asm_bsd_386.s
generated
vendored
29
vendor/golang.org/x/sys/unix/asm_bsd_386.s
generated
vendored
@@ -1,29 +0,0 @@
|
|||||||
// Copyright 2021 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.
|
|
||||||
|
|
||||||
//go:build (freebsd || netbsd || openbsd) && gc
|
|
||||||
// +build freebsd netbsd openbsd
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
// System call support for 386 BSD
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
||||||
29
vendor/golang.org/x/sys/unix/asm_bsd_amd64.s
generated
vendored
29
vendor/golang.org/x/sys/unix/asm_bsd_amd64.s
generated
vendored
@@ -1,29 +0,0 @@
|
|||||||
// Copyright 2021 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.
|
|
||||||
|
|
||||||
//go:build (darwin || dragonfly || freebsd || netbsd || openbsd) && gc
|
|
||||||
// +build darwin dragonfly freebsd netbsd openbsd
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
// System call support for AMD64 BSD
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
||||||
29
vendor/golang.org/x/sys/unix/asm_bsd_arm.s
generated
vendored
29
vendor/golang.org/x/sys/unix/asm_bsd_arm.s
generated
vendored
@@ -1,29 +0,0 @@
|
|||||||
// Copyright 2021 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.
|
|
||||||
|
|
||||||
//go:build (freebsd || netbsd || openbsd) && gc
|
|
||||||
// +build freebsd netbsd openbsd
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
// System call support for ARM BSD
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
B syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
|
||||||
B syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
B syscall·RawSyscall6(SB)
|
|
||||||
29
vendor/golang.org/x/sys/unix/asm_bsd_arm64.s
generated
vendored
29
vendor/golang.org/x/sys/unix/asm_bsd_arm64.s
generated
vendored
@@ -1,29 +0,0 @@
|
|||||||
// Copyright 2021 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.
|
|
||||||
|
|
||||||
//go:build (darwin || freebsd || netbsd || openbsd) && gc
|
|
||||||
// +build darwin freebsd netbsd openbsd
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
// System call support for ARM64 BSD
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
||||||
66
vendor/golang.org/x/sys/unix/asm_linux_386.s
generated
vendored
66
vendor/golang.org/x/sys/unix/asm_linux_386.s
generated
vendored
@@ -1,66 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
//go:build gc
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for 386, Linux
|
|
||||||
//
|
|
||||||
|
|
||||||
// See ../runtime/sys_linux_386.s for the reason why we always use int 0x80
|
|
||||||
// instead of the glibc-specific "CALL 0x10(GS)".
|
|
||||||
#define INVOKE_SYSCALL INT $0x80
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-24
|
|
||||||
CALL runtime·entersyscall(SB)
|
|
||||||
MOVL trap+0(FP), AX // syscall entry
|
|
||||||
MOVL a1+4(FP), BX
|
|
||||||
MOVL a2+8(FP), CX
|
|
||||||
MOVL a3+12(FP), DX
|
|
||||||
MOVL $0, SI
|
|
||||||
MOVL $0, DI
|
|
||||||
INVOKE_SYSCALL
|
|
||||||
MOVL AX, r1+16(FP)
|
|
||||||
MOVL DX, r2+20(FP)
|
|
||||||
CALL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24
|
|
||||||
MOVL trap+0(FP), AX // syscall entry
|
|
||||||
MOVL a1+4(FP), BX
|
|
||||||
MOVL a2+8(FP), CX
|
|
||||||
MOVL a3+12(FP), DX
|
|
||||||
MOVL $0, SI
|
|
||||||
MOVL $0, DI
|
|
||||||
INVOKE_SYSCALL
|
|
||||||
MOVL AX, r1+16(FP)
|
|
||||||
MOVL DX, r2+20(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·socketcall(SB),NOSPLIT,$0-36
|
|
||||||
JMP syscall·socketcall(SB)
|
|
||||||
|
|
||||||
TEXT ·rawsocketcall(SB),NOSPLIT,$0-36
|
|
||||||
JMP syscall·rawsocketcall(SB)
|
|
||||||
|
|
||||||
TEXT ·seek(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·seek(SB)
|
|
||||||
58
vendor/golang.org/x/sys/unix/asm_linux_amd64.s
generated
vendored
58
vendor/golang.org/x/sys/unix/asm_linux_amd64.s
generated
vendored
@@ -1,58 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
//go:build gc
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for AMD64, Linux
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
CALL runtime·entersyscall(SB)
|
|
||||||
MOVQ a1+8(FP), DI
|
|
||||||
MOVQ a2+16(FP), SI
|
|
||||||
MOVQ a3+24(FP), DX
|
|
||||||
MOVQ $0, R10
|
|
||||||
MOVQ $0, R8
|
|
||||||
MOVQ $0, R9
|
|
||||||
MOVQ trap+0(FP), AX // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVQ AX, r1+32(FP)
|
|
||||||
MOVQ DX, r2+40(FP)
|
|
||||||
CALL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
MOVQ a1+8(FP), DI
|
|
||||||
MOVQ a2+16(FP), SI
|
|
||||||
MOVQ a3+24(FP), DX
|
|
||||||
MOVQ $0, R10
|
|
||||||
MOVQ $0, R8
|
|
||||||
MOVQ $0, R9
|
|
||||||
MOVQ trap+0(FP), AX // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVQ AX, r1+32(FP)
|
|
||||||
MOVQ DX, r2+40(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·gettimeofday(SB),NOSPLIT,$0-16
|
|
||||||
JMP syscall·gettimeofday(SB)
|
|
||||||
57
vendor/golang.org/x/sys/unix/asm_linux_arm.s
generated
vendored
57
vendor/golang.org/x/sys/unix/asm_linux_arm.s
generated
vendored
@@ -1,57 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
//go:build gc
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for arm, Linux
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
B syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-24
|
|
||||||
BL runtime·entersyscall(SB)
|
|
||||||
MOVW trap+0(FP), R7
|
|
||||||
MOVW a1+4(FP), R0
|
|
||||||
MOVW a2+8(FP), R1
|
|
||||||
MOVW a3+12(FP), R2
|
|
||||||
MOVW $0, R3
|
|
||||||
MOVW $0, R4
|
|
||||||
MOVW $0, R5
|
|
||||||
SWI $0
|
|
||||||
MOVW R0, r1+16(FP)
|
|
||||||
MOVW $0, R0
|
|
||||||
MOVW R0, r2+20(FP)
|
|
||||||
BL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
B syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24
|
|
||||||
MOVW trap+0(FP), R7 // syscall entry
|
|
||||||
MOVW a1+4(FP), R0
|
|
||||||
MOVW a2+8(FP), R1
|
|
||||||
MOVW a3+12(FP), R2
|
|
||||||
SWI $0
|
|
||||||
MOVW R0, r1+16(FP)
|
|
||||||
MOVW $0, R0
|
|
||||||
MOVW R0, r2+20(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·seek(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·seek(SB)
|
|
||||||
53
vendor/golang.org/x/sys/unix/asm_linux_arm64.s
generated
vendored
53
vendor/golang.org/x/sys/unix/asm_linux_arm64.s
generated
vendored
@@ -1,53 +0,0 @@
|
|||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
//go:build linux && arm64 && gc
|
|
||||||
// +build linux
|
|
||||||
// +build arm64
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
B syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
B syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
BL runtime·entersyscall(SB)
|
|
||||||
MOVD a1+8(FP), R0
|
|
||||||
MOVD a2+16(FP), R1
|
|
||||||
MOVD a3+24(FP), R2
|
|
||||||
MOVD $0, R3
|
|
||||||
MOVD $0, R4
|
|
||||||
MOVD $0, R5
|
|
||||||
MOVD trap+0(FP), R8 // syscall entry
|
|
||||||
SVC
|
|
||||||
MOVD R0, r1+32(FP) // r1
|
|
||||||
MOVD R1, r2+40(FP) // r2
|
|
||||||
BL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
B syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
B syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
MOVD a1+8(FP), R0
|
|
||||||
MOVD a2+16(FP), R1
|
|
||||||
MOVD a3+24(FP), R2
|
|
||||||
MOVD $0, R3
|
|
||||||
MOVD $0, R4
|
|
||||||
MOVD $0, R5
|
|
||||||
MOVD trap+0(FP), R8 // syscall entry
|
|
||||||
SVC
|
|
||||||
MOVD R0, r1+32(FP)
|
|
||||||
MOVD R1, r2+40(FP)
|
|
||||||
RET
|
|
||||||
57
vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
generated
vendored
57
vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
generated
vendored
@@ -1,57 +0,0 @@
|
|||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
//go:build linux && (mips64 || mips64le) && gc
|
|
||||||
// +build linux
|
|
||||||
// +build mips64 mips64le
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for mips64, Linux
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
JAL runtime·entersyscall(SB)
|
|
||||||
MOVV a1+8(FP), R4
|
|
||||||
MOVV a2+16(FP), R5
|
|
||||||
MOVV a3+24(FP), R6
|
|
||||||
MOVV R0, R7
|
|
||||||
MOVV R0, R8
|
|
||||||
MOVV R0, R9
|
|
||||||
MOVV trap+0(FP), R2 // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVV R2, r1+32(FP)
|
|
||||||
MOVV R3, r2+40(FP)
|
|
||||||
JAL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
MOVV a1+8(FP), R4
|
|
||||||
MOVV a2+16(FP), R5
|
|
||||||
MOVV a3+24(FP), R6
|
|
||||||
MOVV R0, R7
|
|
||||||
MOVV R0, R8
|
|
||||||
MOVV R0, R9
|
|
||||||
MOVV trap+0(FP), R2 // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVV R2, r1+32(FP)
|
|
||||||
MOVV R3, r2+40(FP)
|
|
||||||
RET
|
|
||||||
55
vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
generated
vendored
55
vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
generated
vendored
@@ -1,55 +0,0 @@
|
|||||||
// Copyright 2016 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.
|
|
||||||
|
|
||||||
//go:build linux && (mips || mipsle) && gc
|
|
||||||
// +build linux
|
|
||||||
// +build mips mipsle
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for mips, Linux
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-24
|
|
||||||
JAL runtime·entersyscall(SB)
|
|
||||||
MOVW a1+4(FP), R4
|
|
||||||
MOVW a2+8(FP), R5
|
|
||||||
MOVW a3+12(FP), R6
|
|
||||||
MOVW R0, R7
|
|
||||||
MOVW trap+0(FP), R2 // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVW R2, r1+16(FP) // r1
|
|
||||||
MOVW R3, r2+20(FP) // r2
|
|
||||||
JAL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24
|
|
||||||
MOVW a1+4(FP), R4
|
|
||||||
MOVW a2+8(FP), R5
|
|
||||||
MOVW a3+12(FP), R6
|
|
||||||
MOVW trap+0(FP), R2 // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVW R2, r1+16(FP)
|
|
||||||
MOVW R3, r2+20(FP)
|
|
||||||
RET
|
|
||||||
45
vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
generated
vendored
45
vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
generated
vendored
@@ -1,45 +0,0 @@
|
|||||||
// Copyright 2014 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.
|
|
||||||
|
|
||||||
//go:build linux && (ppc64 || ppc64le) && gc
|
|
||||||
// +build linux
|
|
||||||
// +build ppc64 ppc64le
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for ppc64, Linux
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
BL runtime·entersyscall(SB)
|
|
||||||
MOVD a1+8(FP), R3
|
|
||||||
MOVD a2+16(FP), R4
|
|
||||||
MOVD a3+24(FP), R5
|
|
||||||
MOVD R0, R6
|
|
||||||
MOVD R0, R7
|
|
||||||
MOVD R0, R8
|
|
||||||
MOVD trap+0(FP), R9 // syscall entry
|
|
||||||
SYSCALL R9
|
|
||||||
MOVD R3, r1+32(FP)
|
|
||||||
MOVD R4, r2+40(FP)
|
|
||||||
BL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
MOVD a1+8(FP), R3
|
|
||||||
MOVD a2+16(FP), R4
|
|
||||||
MOVD a3+24(FP), R5
|
|
||||||
MOVD R0, R6
|
|
||||||
MOVD R0, R7
|
|
||||||
MOVD R0, R8
|
|
||||||
MOVD trap+0(FP), R9 // syscall entry
|
|
||||||
SYSCALL R9
|
|
||||||
MOVD R3, r1+32(FP)
|
|
||||||
MOVD R4, r2+40(FP)
|
|
||||||
RET
|
|
||||||
49
vendor/golang.org/x/sys/unix/asm_linux_riscv64.s
generated
vendored
49
vendor/golang.org/x/sys/unix/asm_linux_riscv64.s
generated
vendored
@@ -1,49 +0,0 @@
|
|||||||
// Copyright 2019 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.
|
|
||||||
|
|
||||||
//go:build riscv64 && gc
|
|
||||||
// +build riscv64
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for linux/riscv64.
|
|
||||||
//
|
|
||||||
// Where available, just jump to package syscall's implementation of
|
|
||||||
// these functions.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
CALL runtime·entersyscall(SB)
|
|
||||||
MOV a1+8(FP), A0
|
|
||||||
MOV a2+16(FP), A1
|
|
||||||
MOV a3+24(FP), A2
|
|
||||||
MOV trap+0(FP), A7 // syscall entry
|
|
||||||
ECALL
|
|
||||||
MOV A0, r1+32(FP) // r1
|
|
||||||
MOV A1, r2+40(FP) // r2
|
|
||||||
CALL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
MOV a1+8(FP), A0
|
|
||||||
MOV a2+16(FP), A1
|
|
||||||
MOV a3+24(FP), A2
|
|
||||||
MOV trap+0(FP), A7 // syscall entry
|
|
||||||
ECALL
|
|
||||||
MOV A0, r1+32(FP)
|
|
||||||
MOV A1, r2+40(FP)
|
|
||||||
RET
|
|
||||||
57
vendor/golang.org/x/sys/unix/asm_linux_s390x.s
generated
vendored
57
vendor/golang.org/x/sys/unix/asm_linux_s390x.s
generated
vendored
@@ -1,57 +0,0 @@
|
|||||||
// Copyright 2016 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.
|
|
||||||
|
|
||||||
//go:build linux && s390x && gc
|
|
||||||
// +build linux
|
|
||||||
// +build s390x
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for s390x, Linux
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
BR syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
BR syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
BL runtime·entersyscall(SB)
|
|
||||||
MOVD a1+8(FP), R2
|
|
||||||
MOVD a2+16(FP), R3
|
|
||||||
MOVD a3+24(FP), R4
|
|
||||||
MOVD $0, R5
|
|
||||||
MOVD $0, R6
|
|
||||||
MOVD $0, R7
|
|
||||||
MOVD trap+0(FP), R1 // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVD R2, r1+32(FP)
|
|
||||||
MOVD R3, r2+40(FP)
|
|
||||||
BL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
BR syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
BR syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
MOVD a1+8(FP), R2
|
|
||||||
MOVD a2+16(FP), R3
|
|
||||||
MOVD a3+24(FP), R4
|
|
||||||
MOVD $0, R5
|
|
||||||
MOVD $0, R6
|
|
||||||
MOVD $0, R7
|
|
||||||
MOVD trap+0(FP), R1 // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVD R2, r1+32(FP)
|
|
||||||
MOVD R3, r2+40(FP)
|
|
||||||
RET
|
|
||||||
30
vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s
generated
vendored
30
vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s
generated
vendored
@@ -1,30 +0,0 @@
|
|||||||
// Copyright 2019 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.
|
|
||||||
|
|
||||||
//go:build gc
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for mips64, OpenBSD
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
||||||
18
vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
generated
vendored
18
vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
generated
vendored
@@ -1,18 +0,0 @@
|
|||||||
// Copyright 2014 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.
|
|
||||||
|
|
||||||
//go:build gc
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go
|
|
||||||
//
|
|
||||||
|
|
||||||
TEXT ·sysvicall6(SB),NOSPLIT,$0-88
|
|
||||||
JMP syscall·sysvicall6(SB)
|
|
||||||
|
|
||||||
TEXT ·rawSysvicall6(SB),NOSPLIT,$0-88
|
|
||||||
JMP syscall·rawSysvicall6(SB)
|
|
||||||
426
vendor/golang.org/x/sys/unix/asm_zos_s390x.s
generated
vendored
426
vendor/golang.org/x/sys/unix/asm_zos_s390x.s
generated
vendored
@@ -1,426 +0,0 @@
|
|||||||
// Copyright 2020 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.
|
|
||||||
|
|
||||||
//go:build zos && s390x && gc
|
|
||||||
// +build zos
|
|
||||||
// +build s390x
|
|
||||||
// +build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
#define PSALAA 1208(R0)
|
|
||||||
#define GTAB64(x) 80(x)
|
|
||||||
#define LCA64(x) 88(x)
|
|
||||||
#define CAA(x) 8(x)
|
|
||||||
#define EDCHPXV(x) 1016(x) // in the CAA
|
|
||||||
#define SAVSTACK_ASYNC(x) 336(x) // in the LCA
|
|
||||||
|
|
||||||
// SS_*, where x=SAVSTACK_ASYNC
|
|
||||||
#define SS_LE(x) 0(x)
|
|
||||||
#define SS_GO(x) 8(x)
|
|
||||||
#define SS_ERRNO(x) 16(x)
|
|
||||||
#define SS_ERRNOJR(x) 20(x)
|
|
||||||
|
|
||||||
#define LE_CALL BYTE $0x0D; BYTE $0x76; // BL R7, R6
|
|
||||||
|
|
||||||
TEXT ·clearErrno(SB),NOSPLIT,$0-0
|
|
||||||
BL addrerrno<>(SB)
|
|
||||||
MOVD $0, 0(R3)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// Returns the address of errno in R3.
|
|
||||||
TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0
|
|
||||||
// Get library control area (LCA).
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
|
|
||||||
// Get __errno FuncDesc.
|
|
||||||
MOVD CAA(R8), R9
|
|
||||||
MOVD EDCHPXV(R9), R9
|
|
||||||
ADD $(0x156*16), R9
|
|
||||||
LMG 0(R9), R5, R6
|
|
||||||
|
|
||||||
// Switch to saved LE stack.
|
|
||||||
MOVD SAVSTACK_ASYNC(R8), R9
|
|
||||||
MOVD 0(R9), R4
|
|
||||||
MOVD $0, 0(R9)
|
|
||||||
|
|
||||||
// Call __errno function.
|
|
||||||
LE_CALL
|
|
||||||
NOPH
|
|
||||||
|
|
||||||
// Switch back to Go stack.
|
|
||||||
XOR R0, R0 // Restore R0 to $0.
|
|
||||||
MOVD R4, 0(R9) // Save stack pointer.
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·syscall_syscall(SB),NOSPLIT,$0-56
|
|
||||||
BL runtime·entersyscall(SB)
|
|
||||||
MOVD a1+8(FP), R1
|
|
||||||
MOVD a2+16(FP), R2
|
|
||||||
MOVD a3+24(FP), R3
|
|
||||||
|
|
||||||
// Get library control area (LCA).
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
|
|
||||||
// Get function.
|
|
||||||
MOVD CAA(R8), R9
|
|
||||||
MOVD EDCHPXV(R9), R9
|
|
||||||
MOVD trap+0(FP), R5
|
|
||||||
SLD $4, R5
|
|
||||||
ADD R5, R9
|
|
||||||
LMG 0(R9), R5, R6
|
|
||||||
|
|
||||||
// Restore LE stack.
|
|
||||||
MOVD SAVSTACK_ASYNC(R8), R9
|
|
||||||
MOVD 0(R9), R4
|
|
||||||
MOVD $0, 0(R9)
|
|
||||||
|
|
||||||
// Call function.
|
|
||||||
LE_CALL
|
|
||||||
NOPH
|
|
||||||
XOR R0, R0 // Restore R0 to $0.
|
|
||||||
MOVD R4, 0(R9) // Save stack pointer.
|
|
||||||
|
|
||||||
MOVD R3, r1+32(FP)
|
|
||||||
MOVD R0, r2+40(FP)
|
|
||||||
MOVD R0, err+48(FP)
|
|
||||||
MOVW R3, R4
|
|
||||||
CMP R4, $-1
|
|
||||||
BNE done
|
|
||||||
BL addrerrno<>(SB)
|
|
||||||
MOVWZ 0(R3), R3
|
|
||||||
MOVD R3, err+48(FP)
|
|
||||||
done:
|
|
||||||
BL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·syscall_rawsyscall(SB),NOSPLIT,$0-56
|
|
||||||
MOVD a1+8(FP), R1
|
|
||||||
MOVD a2+16(FP), R2
|
|
||||||
MOVD a3+24(FP), R3
|
|
||||||
|
|
||||||
// Get library control area (LCA).
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
|
|
||||||
// Get function.
|
|
||||||
MOVD CAA(R8), R9
|
|
||||||
MOVD EDCHPXV(R9), R9
|
|
||||||
MOVD trap+0(FP), R5
|
|
||||||
SLD $4, R5
|
|
||||||
ADD R5, R9
|
|
||||||
LMG 0(R9), R5, R6
|
|
||||||
|
|
||||||
// Restore LE stack.
|
|
||||||
MOVD SAVSTACK_ASYNC(R8), R9
|
|
||||||
MOVD 0(R9), R4
|
|
||||||
MOVD $0, 0(R9)
|
|
||||||
|
|
||||||
// Call function.
|
|
||||||
LE_CALL
|
|
||||||
NOPH
|
|
||||||
XOR R0, R0 // Restore R0 to $0.
|
|
||||||
MOVD R4, 0(R9) // Save stack pointer.
|
|
||||||
|
|
||||||
MOVD R3, r1+32(FP)
|
|
||||||
MOVD R0, r2+40(FP)
|
|
||||||
MOVD R0, err+48(FP)
|
|
||||||
MOVW R3, R4
|
|
||||||
CMP R4, $-1
|
|
||||||
BNE done
|
|
||||||
BL addrerrno<>(SB)
|
|
||||||
MOVWZ 0(R3), R3
|
|
||||||
MOVD R3, err+48(FP)
|
|
||||||
done:
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·syscall_syscall6(SB),NOSPLIT,$0-80
|
|
||||||
BL runtime·entersyscall(SB)
|
|
||||||
MOVD a1+8(FP), R1
|
|
||||||
MOVD a2+16(FP), R2
|
|
||||||
MOVD a3+24(FP), R3
|
|
||||||
|
|
||||||
// Get library control area (LCA).
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
|
|
||||||
// Get function.
|
|
||||||
MOVD CAA(R8), R9
|
|
||||||
MOVD EDCHPXV(R9), R9
|
|
||||||
MOVD trap+0(FP), R5
|
|
||||||
SLD $4, R5
|
|
||||||
ADD R5, R9
|
|
||||||
LMG 0(R9), R5, R6
|
|
||||||
|
|
||||||
// Restore LE stack.
|
|
||||||
MOVD SAVSTACK_ASYNC(R8), R9
|
|
||||||
MOVD 0(R9), R4
|
|
||||||
MOVD $0, 0(R9)
|
|
||||||
|
|
||||||
// Fill in parameter list.
|
|
||||||
MOVD a4+32(FP), R12
|
|
||||||
MOVD R12, (2176+24)(R4)
|
|
||||||
MOVD a5+40(FP), R12
|
|
||||||
MOVD R12, (2176+32)(R4)
|
|
||||||
MOVD a6+48(FP), R12
|
|
||||||
MOVD R12, (2176+40)(R4)
|
|
||||||
|
|
||||||
// Call function.
|
|
||||||
LE_CALL
|
|
||||||
NOPH
|
|
||||||
XOR R0, R0 // Restore R0 to $0.
|
|
||||||
MOVD R4, 0(R9) // Save stack pointer.
|
|
||||||
|
|
||||||
MOVD R3, r1+56(FP)
|
|
||||||
MOVD R0, r2+64(FP)
|
|
||||||
MOVD R0, err+72(FP)
|
|
||||||
MOVW R3, R4
|
|
||||||
CMP R4, $-1
|
|
||||||
BNE done
|
|
||||||
BL addrerrno<>(SB)
|
|
||||||
MOVWZ 0(R3), R3
|
|
||||||
MOVD R3, err+72(FP)
|
|
||||||
done:
|
|
||||||
BL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·syscall_rawsyscall6(SB),NOSPLIT,$0-80
|
|
||||||
MOVD a1+8(FP), R1
|
|
||||||
MOVD a2+16(FP), R2
|
|
||||||
MOVD a3+24(FP), R3
|
|
||||||
|
|
||||||
// Get library control area (LCA).
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
|
|
||||||
// Get function.
|
|
||||||
MOVD CAA(R8), R9
|
|
||||||
MOVD EDCHPXV(R9), R9
|
|
||||||
MOVD trap+0(FP), R5
|
|
||||||
SLD $4, R5
|
|
||||||
ADD R5, R9
|
|
||||||
LMG 0(R9), R5, R6
|
|
||||||
|
|
||||||
// Restore LE stack.
|
|
||||||
MOVD SAVSTACK_ASYNC(R8), R9
|
|
||||||
MOVD 0(R9), R4
|
|
||||||
MOVD $0, 0(R9)
|
|
||||||
|
|
||||||
// Fill in parameter list.
|
|
||||||
MOVD a4+32(FP), R12
|
|
||||||
MOVD R12, (2176+24)(R4)
|
|
||||||
MOVD a5+40(FP), R12
|
|
||||||
MOVD R12, (2176+32)(R4)
|
|
||||||
MOVD a6+48(FP), R12
|
|
||||||
MOVD R12, (2176+40)(R4)
|
|
||||||
|
|
||||||
// Call function.
|
|
||||||
LE_CALL
|
|
||||||
NOPH
|
|
||||||
XOR R0, R0 // Restore R0 to $0.
|
|
||||||
MOVD R4, 0(R9) // Save stack pointer.
|
|
||||||
|
|
||||||
MOVD R3, r1+56(FP)
|
|
||||||
MOVD R0, r2+64(FP)
|
|
||||||
MOVD R0, err+72(FP)
|
|
||||||
MOVW R3, R4
|
|
||||||
CMP R4, $-1
|
|
||||||
BNE done
|
|
||||||
BL ·rrno<>(SB)
|
|
||||||
MOVWZ 0(R3), R3
|
|
||||||
MOVD R3, err+72(FP)
|
|
||||||
done:
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·syscall_syscall9(SB),NOSPLIT,$0
|
|
||||||
BL runtime·entersyscall(SB)
|
|
||||||
MOVD a1+8(FP), R1
|
|
||||||
MOVD a2+16(FP), R2
|
|
||||||
MOVD a3+24(FP), R3
|
|
||||||
|
|
||||||
// Get library control area (LCA).
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
|
|
||||||
// Get function.
|
|
||||||
MOVD CAA(R8), R9
|
|
||||||
MOVD EDCHPXV(R9), R9
|
|
||||||
MOVD trap+0(FP), R5
|
|
||||||
SLD $4, R5
|
|
||||||
ADD R5, R9
|
|
||||||
LMG 0(R9), R5, R6
|
|
||||||
|
|
||||||
// Restore LE stack.
|
|
||||||
MOVD SAVSTACK_ASYNC(R8), R9
|
|
||||||
MOVD 0(R9), R4
|
|
||||||
MOVD $0, 0(R9)
|
|
||||||
|
|
||||||
// Fill in parameter list.
|
|
||||||
MOVD a4+32(FP), R12
|
|
||||||
MOVD R12, (2176+24)(R4)
|
|
||||||
MOVD a5+40(FP), R12
|
|
||||||
MOVD R12, (2176+32)(R4)
|
|
||||||
MOVD a6+48(FP), R12
|
|
||||||
MOVD R12, (2176+40)(R4)
|
|
||||||
MOVD a7+56(FP), R12
|
|
||||||
MOVD R12, (2176+48)(R4)
|
|
||||||
MOVD a8+64(FP), R12
|
|
||||||
MOVD R12, (2176+56)(R4)
|
|
||||||
MOVD a9+72(FP), R12
|
|
||||||
MOVD R12, (2176+64)(R4)
|
|
||||||
|
|
||||||
// Call function.
|
|
||||||
LE_CALL
|
|
||||||
NOPH
|
|
||||||
XOR R0, R0 // Restore R0 to $0.
|
|
||||||
MOVD R4, 0(R9) // Save stack pointer.
|
|
||||||
|
|
||||||
MOVD R3, r1+80(FP)
|
|
||||||
MOVD R0, r2+88(FP)
|
|
||||||
MOVD R0, err+96(FP)
|
|
||||||
MOVW R3, R4
|
|
||||||
CMP R4, $-1
|
|
||||||
BNE done
|
|
||||||
BL addrerrno<>(SB)
|
|
||||||
MOVWZ 0(R3), R3
|
|
||||||
MOVD R3, err+96(FP)
|
|
||||||
done:
|
|
||||||
BL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·syscall_rawsyscall9(SB),NOSPLIT,$0
|
|
||||||
MOVD a1+8(FP), R1
|
|
||||||
MOVD a2+16(FP), R2
|
|
||||||
MOVD a3+24(FP), R3
|
|
||||||
|
|
||||||
// Get library control area (LCA).
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
|
|
||||||
// Get function.
|
|
||||||
MOVD CAA(R8), R9
|
|
||||||
MOVD EDCHPXV(R9), R9
|
|
||||||
MOVD trap+0(FP), R5
|
|
||||||
SLD $4, R5
|
|
||||||
ADD R5, R9
|
|
||||||
LMG 0(R9), R5, R6
|
|
||||||
|
|
||||||
// Restore LE stack.
|
|
||||||
MOVD SAVSTACK_ASYNC(R8), R9
|
|
||||||
MOVD 0(R9), R4
|
|
||||||
MOVD $0, 0(R9)
|
|
||||||
|
|
||||||
// Fill in parameter list.
|
|
||||||
MOVD a4+32(FP), R12
|
|
||||||
MOVD R12, (2176+24)(R4)
|
|
||||||
MOVD a5+40(FP), R12
|
|
||||||
MOVD R12, (2176+32)(R4)
|
|
||||||
MOVD a6+48(FP), R12
|
|
||||||
MOVD R12, (2176+40)(R4)
|
|
||||||
MOVD a7+56(FP), R12
|
|
||||||
MOVD R12, (2176+48)(R4)
|
|
||||||
MOVD a8+64(FP), R12
|
|
||||||
MOVD R12, (2176+56)(R4)
|
|
||||||
MOVD a9+72(FP), R12
|
|
||||||
MOVD R12, (2176+64)(R4)
|
|
||||||
|
|
||||||
// Call function.
|
|
||||||
LE_CALL
|
|
||||||
NOPH
|
|
||||||
XOR R0, R0 // Restore R0 to $0.
|
|
||||||
MOVD R4, 0(R9) // Save stack pointer.
|
|
||||||
|
|
||||||
MOVD R3, r1+80(FP)
|
|
||||||
MOVD R0, r2+88(FP)
|
|
||||||
MOVD R0, err+96(FP)
|
|
||||||
MOVW R3, R4
|
|
||||||
CMP R4, $-1
|
|
||||||
BNE done
|
|
||||||
BL addrerrno<>(SB)
|
|
||||||
MOVWZ 0(R3), R3
|
|
||||||
MOVD R3, err+96(FP)
|
|
||||||
done:
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
|
|
||||||
TEXT ·svcCall(SB),NOSPLIT,$0
|
|
||||||
BL runtime·save_g(SB) // Save g and stack pointer
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
MOVD SAVSTACK_ASYNC(R8), R9
|
|
||||||
MOVD R15, 0(R9)
|
|
||||||
|
|
||||||
MOVD argv+8(FP), R1 // Move function arguments into registers
|
|
||||||
MOVD dsa+16(FP), g
|
|
||||||
MOVD fnptr+0(FP), R15
|
|
||||||
|
|
||||||
BYTE $0x0D // Branch to function
|
|
||||||
BYTE $0xEF
|
|
||||||
|
|
||||||
BL runtime·load_g(SB) // Restore g and stack pointer
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
MOVD SAVSTACK_ASYNC(R8), R9
|
|
||||||
MOVD 0(R9), R15
|
|
||||||
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func svcLoad(name *byte) unsafe.Pointer
|
|
||||||
TEXT ·svcLoad(SB),NOSPLIT,$0
|
|
||||||
MOVD R15, R2 // Save go stack pointer
|
|
||||||
MOVD name+0(FP), R0 // Move SVC args into registers
|
|
||||||
MOVD $0x80000000, R1
|
|
||||||
MOVD $0, R15
|
|
||||||
BYTE $0x0A // SVC 08 LOAD
|
|
||||||
BYTE $0x08
|
|
||||||
MOVW R15, R3 // Save return code from SVC
|
|
||||||
MOVD R2, R15 // Restore go stack pointer
|
|
||||||
CMP R3, $0 // Check SVC return code
|
|
||||||
BNE error
|
|
||||||
|
|
||||||
MOVD $-2, R3 // Reset last bit of entry point to zero
|
|
||||||
AND R0, R3
|
|
||||||
MOVD R3, addr+8(FP) // Return entry point returned by SVC
|
|
||||||
CMP R0, R3 // Check if last bit of entry point was set
|
|
||||||
BNE done
|
|
||||||
|
|
||||||
MOVD R15, R2 // Save go stack pointer
|
|
||||||
MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08)
|
|
||||||
BYTE $0x0A // SVC 09 DELETE
|
|
||||||
BYTE $0x09
|
|
||||||
MOVD R2, R15 // Restore go stack pointer
|
|
||||||
|
|
||||||
error:
|
|
||||||
MOVD $0, addr+8(FP) // Return 0 on failure
|
|
||||||
done:
|
|
||||||
XOR R0, R0 // Reset r0 to 0
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func svcUnload(name *byte, fnptr unsafe.Pointer) int64
|
|
||||||
TEXT ·svcUnload(SB),NOSPLIT,$0
|
|
||||||
MOVD R15, R2 // Save go stack pointer
|
|
||||||
MOVD name+0(FP), R0 // Move SVC args into registers
|
|
||||||
MOVD addr+8(FP), R15
|
|
||||||
BYTE $0x0A // SVC 09
|
|
||||||
BYTE $0x09
|
|
||||||
XOR R0, R0 // Reset r0 to 0
|
|
||||||
MOVD R15, R1 // Save SVC return code
|
|
||||||
MOVD R2, R15 // Restore go stack pointer
|
|
||||||
MOVD R1, rc+0(FP) // Return SVC return code
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func gettid() uint64
|
|
||||||
TEXT ·gettid(SB), NOSPLIT, $0
|
|
||||||
// Get library control area (LCA).
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
|
|
||||||
// Get CEECAATHDID
|
|
||||||
MOVD CAA(R8), R9
|
|
||||||
MOVD 0x3D0(R9), R9
|
|
||||||
MOVD R9, ret+0(FP)
|
|
||||||
|
|
||||||
RET
|
|
||||||
36
vendor/golang.org/x/sys/unix/bluetooth_linux.go
generated
vendored
36
vendor/golang.org/x/sys/unix/bluetooth_linux.go
generated
vendored
@@ -1,36 +0,0 @@
|
|||||||
// Copyright 2016 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.
|
|
||||||
|
|
||||||
// Bluetooth sockets and messages
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Bluetooth Protocols
|
|
||||||
const (
|
|
||||||
BTPROTO_L2CAP = 0
|
|
||||||
BTPROTO_HCI = 1
|
|
||||||
BTPROTO_SCO = 2
|
|
||||||
BTPROTO_RFCOMM = 3
|
|
||||||
BTPROTO_BNEP = 4
|
|
||||||
BTPROTO_CMTP = 5
|
|
||||||
BTPROTO_HIDP = 6
|
|
||||||
BTPROTO_AVDTP = 7
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
HCI_CHANNEL_RAW = 0
|
|
||||||
HCI_CHANNEL_USER = 1
|
|
||||||
HCI_CHANNEL_MONITOR = 2
|
|
||||||
HCI_CHANNEL_CONTROL = 3
|
|
||||||
HCI_CHANNEL_LOGGING = 4
|
|
||||||
)
|
|
||||||
|
|
||||||
// Socketoption Level
|
|
||||||
const (
|
|
||||||
SOL_BLUETOOTH = 0x112
|
|
||||||
SOL_HCI = 0x0
|
|
||||||
SOL_L2CAP = 0x6
|
|
||||||
SOL_RFCOMM = 0x12
|
|
||||||
SOL_SCO = 0x11
|
|
||||||
)
|
|
||||||
196
vendor/golang.org/x/sys/unix/cap_freebsd.go
generated
vendored
196
vendor/golang.org/x/sys/unix/cap_freebsd.go
generated
vendored
@@ -1,196 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
//go:build freebsd
|
|
||||||
// +build freebsd
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Go implementation of C mostly found in /usr/src/sys/kern/subr_capability.c
|
|
||||||
|
|
||||||
const (
|
|
||||||
// This is the version of CapRights this package understands. See C implementation for parallels.
|
|
||||||
capRightsGoVersion = CAP_RIGHTS_VERSION_00
|
|
||||||
capArSizeMin = CAP_RIGHTS_VERSION_00 + 2
|
|
||||||
capArSizeMax = capRightsGoVersion + 2
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
bit2idx = []int{
|
|
||||||
-1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func capidxbit(right uint64) int {
|
|
||||||
return int((right >> 57) & 0x1f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func rightToIndex(right uint64) (int, error) {
|
|
||||||
idx := capidxbit(right)
|
|
||||||
if idx < 0 || idx >= len(bit2idx) {
|
|
||||||
return -2, fmt.Errorf("index for right 0x%x out of range", right)
|
|
||||||
}
|
|
||||||
return bit2idx[idx], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func caprver(right uint64) int {
|
|
||||||
return int(right >> 62)
|
|
||||||
}
|
|
||||||
|
|
||||||
func capver(rights *CapRights) int {
|
|
||||||
return caprver(rights.Rights[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func caparsize(rights *CapRights) int {
|
|
||||||
return capver(rights) + 2
|
|
||||||
}
|
|
||||||
|
|
||||||
// CapRightsSet sets the permissions in setrights in rights.
|
|
||||||
func CapRightsSet(rights *CapRights, setrights []uint64) error {
|
|
||||||
// This is essentially a copy of cap_rights_vset()
|
|
||||||
if capver(rights) != CAP_RIGHTS_VERSION_00 {
|
|
||||||
return fmt.Errorf("bad rights version %d", capver(rights))
|
|
||||||
}
|
|
||||||
|
|
||||||
n := caparsize(rights)
|
|
||||||
if n < capArSizeMin || n > capArSizeMax {
|
|
||||||
return errors.New("bad rights size")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, right := range setrights {
|
|
||||||
if caprver(right) != CAP_RIGHTS_VERSION_00 {
|
|
||||||
return errors.New("bad right version")
|
|
||||||
}
|
|
||||||
i, err := rightToIndex(right)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if i >= n {
|
|
||||||
return errors.New("index overflow")
|
|
||||||
}
|
|
||||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
|
||||||
return errors.New("index mismatch")
|
|
||||||
}
|
|
||||||
rights.Rights[i] |= right
|
|
||||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
|
||||||
return errors.New("index mismatch (after assign)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CapRightsClear clears the permissions in clearrights from rights.
|
|
||||||
func CapRightsClear(rights *CapRights, clearrights []uint64) error {
|
|
||||||
// This is essentially a copy of cap_rights_vclear()
|
|
||||||
if capver(rights) != CAP_RIGHTS_VERSION_00 {
|
|
||||||
return fmt.Errorf("bad rights version %d", capver(rights))
|
|
||||||
}
|
|
||||||
|
|
||||||
n := caparsize(rights)
|
|
||||||
if n < capArSizeMin || n > capArSizeMax {
|
|
||||||
return errors.New("bad rights size")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, right := range clearrights {
|
|
||||||
if caprver(right) != CAP_RIGHTS_VERSION_00 {
|
|
||||||
return errors.New("bad right version")
|
|
||||||
}
|
|
||||||
i, err := rightToIndex(right)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if i >= n {
|
|
||||||
return errors.New("index overflow")
|
|
||||||
}
|
|
||||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
|
||||||
return errors.New("index mismatch")
|
|
||||||
}
|
|
||||||
rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF)
|
|
||||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
|
||||||
return errors.New("index mismatch (after assign)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CapRightsIsSet checks whether all the permissions in setrights are present in rights.
|
|
||||||
func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) {
|
|
||||||
// This is essentially a copy of cap_rights_is_vset()
|
|
||||||
if capver(rights) != CAP_RIGHTS_VERSION_00 {
|
|
||||||
return false, fmt.Errorf("bad rights version %d", capver(rights))
|
|
||||||
}
|
|
||||||
|
|
||||||
n := caparsize(rights)
|
|
||||||
if n < capArSizeMin || n > capArSizeMax {
|
|
||||||
return false, errors.New("bad rights size")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, right := range setrights {
|
|
||||||
if caprver(right) != CAP_RIGHTS_VERSION_00 {
|
|
||||||
return false, errors.New("bad right version")
|
|
||||||
}
|
|
||||||
i, err := rightToIndex(right)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if i >= n {
|
|
||||||
return false, errors.New("index overflow")
|
|
||||||
}
|
|
||||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
|
||||||
return false, errors.New("index mismatch")
|
|
||||||
}
|
|
||||||
if (rights.Rights[i] & right) != right {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func capright(idx uint64, bit uint64) uint64 {
|
|
||||||
return ((1 << (57 + idx)) | bit)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CapRightsInit returns a pointer to an initialised CapRights structure filled with rights.
|
|
||||||
// See man cap_rights_init(3) and rights(4).
|
|
||||||
func CapRightsInit(rights []uint64) (*CapRights, error) {
|
|
||||||
var r CapRights
|
|
||||||
r.Rights[0] = (capRightsGoVersion << 62) | capright(0, 0)
|
|
||||||
r.Rights[1] = capright(1, 0)
|
|
||||||
|
|
||||||
err := CapRightsSet(&r, rights)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CapRightsLimit reduces the operations permitted on fd to at most those contained in rights.
|
|
||||||
// The capability rights on fd can never be increased by CapRightsLimit.
|
|
||||||
// See man cap_rights_limit(2) and rights(4).
|
|
||||||
func CapRightsLimit(fd uintptr, rights *CapRights) error {
|
|
||||||
return capRightsLimit(int(fd), rights)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CapRightsGet returns a CapRights structure containing the operations permitted on fd.
|
|
||||||
// See man cap_rights_get(3) and rights(4).
|
|
||||||
func CapRightsGet(fd uintptr) (*CapRights, error) {
|
|
||||||
r, err := CapRightsInit(nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = capRightsGet(capRightsGoVersion, int(fd), r)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return r, nil
|
|
||||||
}
|
|
||||||
14
vendor/golang.org/x/sys/unix/constants.go
generated
vendored
14
vendor/golang.org/x/sys/unix/constants.go
generated
vendored
@@ -1,14 +0,0 @@
|
|||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
|
||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
const (
|
|
||||||
R_OK = 0x4
|
|
||||||
W_OK = 0x2
|
|
||||||
X_OK = 0x1
|
|
||||||
)
|
|
||||||
27
vendor/golang.org/x/sys/unix/dev_aix_ppc.go
generated
vendored
27
vendor/golang.org/x/sys/unix/dev_aix_ppc.go
generated
vendored
@@ -1,27 +0,0 @@
|
|||||||
// Copyright 2018 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.
|
|
||||||
|
|
||||||
//go:build aix && ppc
|
|
||||||
// +build aix,ppc
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used by AIX.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of a Linux device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
return uint32((dev >> 16) & 0xffff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of a Linux device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
return uint32(dev & 0xffff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns a Linux device number generated from the given major and minor
|
|
||||||
// components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
return uint64(((major) << 16) | (minor))
|
|
||||||
}
|
|
||||||
29
vendor/golang.org/x/sys/unix/dev_aix_ppc64.go
generated
vendored
29
vendor/golang.org/x/sys/unix/dev_aix_ppc64.go
generated
vendored
@@ -1,29 +0,0 @@
|
|||||||
// Copyright 2018 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.
|
|
||||||
|
|
||||||
//go:build aix && ppc64
|
|
||||||
// +build aix,ppc64
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used AIX.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of a Linux device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
return uint32((dev & 0x3fffffff00000000) >> 32)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of a Linux device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
return uint32((dev & 0x00000000ffffffff) >> 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns a Linux device number generated from the given major and minor
|
|
||||||
// components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
var DEVNO64 uint64
|
|
||||||
DEVNO64 = 0x8000000000000000
|
|
||||||
return ((uint64(major) << 32) | (uint64(minor) & 0x00000000FFFFFFFF) | DEVNO64)
|
|
||||||
}
|
|
||||||
24
vendor/golang.org/x/sys/unix/dev_darwin.go
generated
vendored
24
vendor/golang.org/x/sys/unix/dev_darwin.go
generated
vendored
@@ -1,24 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used in Darwin's sys/types.h header.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of a Darwin device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
return uint32((dev >> 24) & 0xff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of a Darwin device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
return uint32(dev & 0xffffff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns a Darwin device number generated from the given major and minor
|
|
||||||
// components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
return (uint64(major) << 24) | uint64(minor)
|
|
||||||
}
|
|
||||||
30
vendor/golang.org/x/sys/unix/dev_dragonfly.go
generated
vendored
30
vendor/golang.org/x/sys/unix/dev_dragonfly.go
generated
vendored
@@ -1,30 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used in Dragonfly's sys/types.h header.
|
|
||||||
//
|
|
||||||
// The information below is extracted and adapted from sys/types.h:
|
|
||||||
//
|
|
||||||
// Minor gives a cookie instead of an index since in order to avoid changing the
|
|
||||||
// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for
|
|
||||||
// devices that don't use them.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of a DragonFlyBSD device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
return uint32((dev >> 8) & 0xff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of a DragonFlyBSD device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
return uint32(dev & 0xffff00ff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns a DragonFlyBSD device number generated from the given major and
|
|
||||||
// minor components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
return (uint64(major) << 8) | uint64(minor)
|
|
||||||
}
|
|
||||||
30
vendor/golang.org/x/sys/unix/dev_freebsd.go
generated
vendored
30
vendor/golang.org/x/sys/unix/dev_freebsd.go
generated
vendored
@@ -1,30 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used in FreeBSD's sys/types.h header.
|
|
||||||
//
|
|
||||||
// The information below is extracted and adapted from sys/types.h:
|
|
||||||
//
|
|
||||||
// Minor gives a cookie instead of an index since in order to avoid changing the
|
|
||||||
// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for
|
|
||||||
// devices that don't use them.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of a FreeBSD device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
return uint32((dev >> 8) & 0xff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of a FreeBSD device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
return uint32(dev & 0xffff00ff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns a FreeBSD device number generated from the given major and
|
|
||||||
// minor components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
return (uint64(major) << 8) | uint64(minor)
|
|
||||||
}
|
|
||||||
42
vendor/golang.org/x/sys/unix/dev_linux.go
generated
vendored
42
vendor/golang.org/x/sys/unix/dev_linux.go
generated
vendored
@@ -1,42 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used by the Linux kernel and glibc.
|
|
||||||
//
|
|
||||||
// The information below is extracted and adapted from bits/sysmacros.h in the
|
|
||||||
// glibc sources:
|
|
||||||
//
|
|
||||||
// dev_t in glibc is 64-bit, with 32-bit major and minor numbers. glibc's
|
|
||||||
// default encoding is MMMM Mmmm mmmM MMmm, where M is a hex digit of the major
|
|
||||||
// number and m is a hex digit of the minor number. This is backward compatible
|
|
||||||
// with legacy systems where dev_t is 16 bits wide, encoded as MMmm. It is also
|
|
||||||
// backward compatible with the Linux kernel, which for some architectures uses
|
|
||||||
// 32-bit dev_t, encoded as mmmM MMmm.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of a Linux device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
major := uint32((dev & 0x00000000000fff00) >> 8)
|
|
||||||
major |= uint32((dev & 0xfffff00000000000) >> 32)
|
|
||||||
return major
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of a Linux device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
minor := uint32((dev & 0x00000000000000ff) >> 0)
|
|
||||||
minor |= uint32((dev & 0x00000ffffff00000) >> 12)
|
|
||||||
return minor
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns a Linux device number generated from the given major and minor
|
|
||||||
// components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
dev := (uint64(major) & 0x00000fff) << 8
|
|
||||||
dev |= (uint64(major) & 0xfffff000) << 32
|
|
||||||
dev |= (uint64(minor) & 0x000000ff) << 0
|
|
||||||
dev |= (uint64(minor) & 0xffffff00) << 12
|
|
||||||
return dev
|
|
||||||
}
|
|
||||||
29
vendor/golang.org/x/sys/unix/dev_netbsd.go
generated
vendored
29
vendor/golang.org/x/sys/unix/dev_netbsd.go
generated
vendored
@@ -1,29 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used in NetBSD's sys/types.h header.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of a NetBSD device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
return uint32((dev & 0x000fff00) >> 8)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of a NetBSD device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
minor := uint32((dev & 0x000000ff) >> 0)
|
|
||||||
minor |= uint32((dev & 0xfff00000) >> 12)
|
|
||||||
return minor
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns a NetBSD device number generated from the given major and minor
|
|
||||||
// components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
dev := (uint64(major) << 8) & 0x000fff00
|
|
||||||
dev |= (uint64(minor) << 12) & 0xfff00000
|
|
||||||
dev |= (uint64(minor) << 0) & 0x000000ff
|
|
||||||
return dev
|
|
||||||
}
|
|
||||||
29
vendor/golang.org/x/sys/unix/dev_openbsd.go
generated
vendored
29
vendor/golang.org/x/sys/unix/dev_openbsd.go
generated
vendored
@@ -1,29 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used in OpenBSD's sys/types.h header.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of an OpenBSD device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
return uint32((dev & 0x0000ff00) >> 8)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of an OpenBSD device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
minor := uint32((dev & 0x000000ff) >> 0)
|
|
||||||
minor |= uint32((dev & 0xffff0000) >> 8)
|
|
||||||
return minor
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns an OpenBSD device number generated from the given major and minor
|
|
||||||
// components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
dev := (uint64(major) << 8) & 0x0000ff00
|
|
||||||
dev |= (uint64(minor) << 8) & 0xffff0000
|
|
||||||
dev |= (uint64(minor) << 0) & 0x000000ff
|
|
||||||
return dev
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user