package zapjournal
import (
)
const memfdName = "zapjournal"
func () (bool, error) {
, := os.Stat(socketPath)
switch {
case os.IsNotExist():
return false, nil
case != nil:
return false,
default:
return true, nil
}
}
func ( UnixConn, Config) zapcore.Core {
:= getVarsEncoder(.Prefix)
return &journalCore{
LevelEnabler: .Level,
path: .Path,
conn: ,
enc: ,
}
}
type journalCore struct {
zapcore.LevelEnabler
path string
conn UnixConn
enc *varsEncoder
}
func ( *journalCore) ( []zapcore.Field) zapcore.Core {
:= cloneVarsEncoder(.enc)
addFields(, )
return &journalCore{
LevelEnabler: .LevelEnabler,
path: .path,
conn: .conn,
enc: ,
}
}
func ( *journalCore) ( zapcore.Entry, []zapcore.Field) error {
:= .enc.encodeEntry(, )
defer putVarsEncoder()
:= &net.UnixAddr{
Name: .path,
Net: "unixgram",
}
, , := .conn.WriteMsgUnix(.buf, nil, )
if == nil {
return nil
}
if !isSocketSpaceError() {
return
}
, := unix.MemfdCreate(memfdName, unix.MFD_CLOEXEC|unix.MFD_ALLOW_SEALING)
if != nil {
return fmt.Errorf("create memfd: %w", )
}
:= os.NewFile(uintptr(), memfdName)
defer func() { _ = .Close() }()
if , := .Write(.buf); != nil {
return fmt.Errorf("write to memfd: %w", )
}
:= unix.F_SEAL_SHRINK | unix.F_SEAL_GROW | unix.F_SEAL_WRITE | unix.F_SEAL_SEAL
if , := unix.FcntlInt(uintptr(), unix.F_ADD_SEALS, ); != nil {
return fmt.Errorf("seal memfd: %w", )
}
:= unix.UnixRights()
_, _, = .conn.WriteMsgUnix(nil, , )
return
}
func ( *journalCore) ( zapcore.Entry, *zapcore.CheckedEntry) *zapcore.CheckedEntry {
if .Enabled(.Level) {
return .AddCore(, )
}
return
}
func ( *journalCore) () error {
return nil
}
func ( error) bool {
, := .(*net.OpError)
if ! || == nil {
return false
}
, := .Err.(*os.SyscallError)
if ! || == nil {
return false
}
return .Err == unix.EMSGSIZE || .Err == unix.ENOBUFS
}