github.com/qioalice/ekago/v3@v3.3.2-0.20221202205325-5c262d586ee4/ekalog/entry_private.go (about) 1 // Copyright © 2020-2021. All rights reserved. 2 // Author: Ilya Stroy. 3 // Contacts: iyuryevich@pm.me, https://github.com/qioalice 4 // License: https://opensource.org/licenses/MIT 5 6 package ekalog 7 8 import ( 9 "runtime" 10 11 "github.com/qioalice/ekago/v3/ekasys" 12 "github.com/qioalice/ekago/v3/internal/ekaletter" 13 ) 14 15 // prepare prepares current Entry for being used assuming that Entry has been 16 // obtained from the Entry's pool. Returns prepared Entry. 17 func (e *Entry) prepare() *Entry { 18 19 // Because we can't detect when work with Entry is done while user chains 20 // Logger's method (with Entry cloning), we must use runtime.SetFinalizer() 21 // to return Entry to the its pool. 22 if e.needSetFinalizer { 23 runtime.SetFinalizer(e, releaseEntryForFinalizer) 24 e.needSetFinalizer = false 25 } 26 27 return e 28 } 29 30 // cleanup frees all allocated resources (RAM in 99% cases) by Entry, preparing 31 // it for being returned to the pool and being reused in the future. 32 func (e *Entry) cleanup() (this *Entry) { 33 34 e.l = nil 35 e.LogLetter.StackTrace = nil 36 e.ErrLetter = nil 37 38 ekaletter.LReset(e.LogLetter) 39 return e 40 } 41 42 // clone clones the current Entry and returns it copy. It takes a new Entry 43 // object from its pool to avoid unnecessary RAM allocations. 44 func (e *Entry) clone() *Entry { 45 46 clonedEntry := acquireEntry() 47 48 // Clone Fields using most efficient way. 49 // Do not allocate RAM if it's already allocated (but nulled). 50 if lFrom := len(e.LogLetter.Fields); lFrom > 0 { 51 if cTo := cap(clonedEntry.LogLetter.Fields); cTo < lFrom { 52 clonedEntry.LogLetter.Fields = make([]ekaletter.LetterField, lFrom) 53 } else { 54 // lFrom <= cTo, it's ok to do that 55 clonedEntry.LogLetter.Fields = 56 clonedEntry.LogLetter.Fields[:lFrom] 57 } 58 for i := 0; i < lFrom; i++ { 59 clonedEntry.LogLetter.Fields[i] = e.LogLetter.Fields[i] 60 } 61 } 62 63 // There is no need to zero Time, Level, LetterMessage fields 64 // because they used only in one place and will be overwritten anyway. 65 66 return clonedEntry 67 } 68 69 // addStacktraceIfNotPresented generates and adds stacktrace 70 // (if it's not presented by ErrLetter's field). 71 func (e *Entry) addStacktraceIfNotPresented() (this *Entry) { 72 if e.ErrLetter == nil { 73 e.LogLetter.StackTrace = ekasys.GetStackTrace(3, -1).ExcludeInternal() 74 } 75 return e 76 }