pkg/log/cached_log_field_extractor.go (83 lines of code) (raw):
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package log
import (
"sync"
"time"
"github.com/GoogleCloudPlatform/khi/pkg/model/enum"
)
// CachedLogFieldExtractor implements CommonLogFieldExtractor and call the parent CommonLogFieldExtractor only when it was needed
// because accessing log fields from the Reader interface is a heavy operation.
type CachedLogFieldExtractor struct {
id string
timestamp time.Time
hasTimestamp bool
mainMessage string
severity enum.Severity
displayID string
parent CommonLogFieldExtractor
logBody string
lock sync.Mutex
}
func NewCachedLogFieldExtractor(parent CommonLogFieldExtractor) *CachedLogFieldExtractor {
return &CachedLogFieldExtractor{parent: parent}
}
// LogBody implements CommonLogFieldExtractor.
func (c *CachedLogFieldExtractor) LogBody(l *LogEntity) string {
c.lock.Lock()
defer c.lock.Unlock()
if c.logBody == "" {
c.logBody = c.parent.LogBody(l)
}
return c.logBody
}
// SetLogBodyCacheDirect set the given logBody as the cache of LogBody.
func (c *CachedLogFieldExtractor) SetLogBodyCacheDirect(logBody string) {
c.lock.Lock()
defer c.lock.Unlock()
c.logBody = logBody
}
// DisplayID implements CommonLogFieldExtractor.
func (c *CachedLogFieldExtractor) DisplayID(l *LogEntity) string {
c.lock.Lock()
defer c.lock.Unlock()
if c.displayID == "" {
c.displayID = c.parent.DisplayID(l)
}
return c.displayID
}
// ID implements CommonLogFieldExtractor.
func (c *CachedLogFieldExtractor) ID(l *LogEntity) string {
c.lock.Lock()
defer c.lock.Unlock()
if c.id == "" {
c.id = c.parent.ID(l)
}
return c.id
}
// MainMessage implements CommonLogFieldExtractor.
func (c *CachedLogFieldExtractor) MainMessage(l *LogEntity) (string, error) {
c.lock.Lock()
defer c.lock.Unlock()
if c.mainMessage == "" {
mainMessage, err := c.parent.MainMessage(l)
if err != nil {
return "", err
}
c.mainMessage = mainMessage
}
return c.mainMessage, nil
}
// Severity implements CommonLogFieldExtractor.
func (c *CachedLogFieldExtractor) Severity(l *LogEntity) (enum.Severity, error) {
c.lock.Lock()
defer c.lock.Unlock()
if c.severity == enum.SeverityUnknown {
severity, err := c.parent.Severity(l)
if err != nil {
return enum.SeverityUnknown, err
}
c.severity = severity
}
return c.severity, nil
}
// Timestamp implements CommonLogFieldExtractor.
func (c *CachedLogFieldExtractor) Timestamp(l *LogEntity) time.Time {
c.lock.Lock()
defer c.lock.Unlock()
if !c.hasTimestamp {
c.timestamp = c.parent.Timestamp(l)
c.hasTimestamp = true
}
return c.timestamp
}
var _ CommonLogFieldExtractor = (*CachedLogFieldExtractor)(nil)