Coder Social home page Coder Social logo

Comments (3)

tonyghita avatar tonyghita commented on June 15, 2024

I'm finding the same behavior with https://github.com/uber-go/zap. Logs are non-deterministically picked up from stderr by the CloudWatch Logs agent.

zap opens stderr as a write-only file, in append, asynchronous I/O mode. I think Lambda has trouble picking up the async I/O. zerolog may be doing something similar.

In your example, you could add a os.Stderr.Sync() before exiting or after writing a line.

var handlerInitialized = false
var chiAdapter *chiadapter.ChiLambda
var logger *zerolog.Logger

func Handler(req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	if !handlerInitialized {
		logger = zerolog.New(os.Stderr)
		logger.Info("cold_start")

		api := server.NewAPI(&logger)
		chiAdapter = chiadapter.New(api.Router())
		handlerInitialized = true
	}

	return chiAdapter.Proxy(req)
}

func main() {
	lambda.Start(Handler)
        if err := os.Stderr.Sync(); err != nil {
            log.Println(err)
        } // force synchronous write to /dev/stderr before exiting
}

from aws-lambda-go.

amanbolat avatar amanbolat commented on June 15, 2024

@tonyghita I will try to add os.Stderr.Sync() but i found that sometimes any code running after lambda.Start(Handler) will not work.

from aws-lambda-go.

tonyghita avatar tonyghita commented on June 15, 2024

Ahh, good point. lambda.Start() won't return.

I created a hook using zap to sync os.Stderr after every log entry.

// flush() is a logger Hook for flushing the log file after every entry.
// This is more expensive than using the default asynchronous I/O, but
// necessary for Lambda to pick up each log line.
// Don't do this in performance-sensitive applications.
func flush(f *os.File) func(zapcore.Entry) error {
	return func(zapcore.Entry) error {
		if f != nil {
			_ = f.Sync()
		}
		return nil
	}
}

// New creates a new logger that writes to /dev/stderr and syncs after every log entry.
// The syncing is necessary because AWS Lambda does not handle asynchronous I/O well.
func New() (*Logger, error) {
	log, err := zap.NewProduction(zap.Hooks(flush(os.Stderr)))
	if err != nil {
		return nil, err
	}

	return &Logger{log: log}, nil
}

I'm not familiar with zerolog, but maybe it provides a similar functionality?

from aws-lambda-go.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.