Giter Site home page Giter Site logo

log's Introduction

No longer maintained

This software is no longer being maintainted and should not be chosen for new projects. See this issue for more information

Apex Serverless Architecture

Apex lets you build, deploy, and manage AWS Lambda functions with ease. With Apex you can use languages that are not natively supported by AWS Lambda through the use of a Node.js shim injected into the build. A variety of workflow related tooling is provided for testing functions, rolling back deploys, viewing metrics, tailing logs, hooking into the build system and more.

This project is designed for event-driven pipelines as it does not abstract away FaaS (functions as a service). If you are building web applications, APIs, or sites, consider using Apex Up, which provides a more out-of-the-box experience for these use-cases.

Installation

On macOS, Linux, or OpenBSD run the following:

curl https://raw.githubusercontent.com/apex/apex/master/install.sh | sh

Note that you may need to run the sudo version below, or alternatively chown /usr/local:

curl https://raw.githubusercontent.com/apex/apex/master/install.sh | sudo sh

On Windows download binary.

After downloading, rename binary file 'apex.exe', then add to PATH.

If already installed, upgrade with:

apex upgrade

Runtimes

Currently supports:

  • Node.js
  • Golang
  • Python
  • Ruby
  • Java
  • Rust
  • Clojure

Example projects for all supported runtimes can be found in _examples directory.

Features

  • Supports languages Lambda does not natively support via shim
  • Binary install (install apex quickly for continuous deployment in CI etc)
  • Hook support for running commands (transpile code, lint, dependency management, etc)
  • Batteries included but optional (opt-in to higher level abstractions)
  • Environment variable population via command-line, file, or inline config
  • Idempotent deployments (checksums skip already-deployed code)
  • Multiple environments via project.ENV.json and function.ENV.json files
  • Configuration inheritance and overrides
  • Command-line function invocation with JSON streams
  • Command & function name autocompletion
  • Function name globbing (ex: apex deploy api_*)
  • Transparently generates a zip for your deploy
  • Project bootstrapping with optional Terraform support
  • Function metrics and cost analysis
  • Ignore deploying files with .apexignore
  • Function rollback support
  • Tail function logs
  • Concurrency for quick deploys
  • Dry-run to preview changes
  • VPC support
  • Multiple region support
  • Lambda@Edge support

Sponsors

Does your company use Apex? Help keep the project bug-free and feature rich by sponsoring the project.

Backers

Love our work and community? Become a backer.

Example

Apex projects are made up of a project.json configuration file, and zero or more Lambda functions defined in the "functions" directory. Here's an example file structure:

project.json
functions
├── bar
│   ├── function.json
│   └── index.js
└── foo
    ├── function.json
    └── index.js

The project.json file defines project level configuration that applies to all functions, and defines dependencies. For this simple example the following will do:

{
  "name": "example",
  "description": "Example project"
}

Each function uses a function.json configuration file to define function-specific properties such as the runtime, amount of memory allocated, and timeout. This file is completely optional, as you can specify defaults in your project.json file. For example:

{
  "name": "bar",
  "description": "Node.js example function",
  "runtime": "nodejs4.3",
  "memory": 128,
  "timeout": 5,
  "role": "arn:aws:iam::293503197324:role/lambda"
}

Now the directory structure for your project would be:

project.json
functions
├── bar
│   └── index.js
└── foo
    └── index.js

Finally the source for the functions themselves look like this in Node.js:

console.log('start bar')
exports.handle = function(e, ctx) {
  ctx.succeed({ hello: e.name })
}

Apex operates at the project level, but many commands allow you to specify specific functions. For example you may deploy the entire project with a single command:

$ apex deploy

Or whitelist functions to deploy:

$ apex deploy foo bar

Invoke it!

$ echo '{ "name": "Tobi" }' | apex invoke bar
{ "hello": "Tobi" }

See the Documentation for more information.

Links


Build Status Slack Status GoDoc OpenCollective OpenCollective

log's People

Contributors

abenerd avatar aviau avatar caarlos0 avatar davidtpate avatar dobegor avatar f2prateek avatar flowonyx avatar francoishill avatar gmwxio avatar matthewmueller avatar oelshocht avatar patrickmn avatar tj avatar wesleimp avatar yields avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

log's Issues

Individual levels for multi handler

It would be nice when using the multi handler if we could set the individual logging level for each handler. For example in my application I only want info to be logged to the cli and Warn, Error, and Fatal to be written out as json to a file.

Based on an initial look this might require a lot of changes since Level is currently part of the Logger struct.

Message -> Type

The name message just implies unboundedness, type sets people up for correct usage.

Lazy fields

It would be nice to have an optional WithLazyFields(key string, func() interface{}) method to calculate field value only when it's retrieved with Get(key string) method.

I.e. some entries may be discarded due to log level, but they are still evaluated.

A real life example is dumping http requests/responses on debug level. It requires much more memory for each request to process, and it's painful to have some debug switches to turn it on/off on local/production system.

CLI

I've been using this to prettify tailing logs from production (similar to the bunyan cli). Worth adding to the main project?

package main

import (
    "bufio"
    "encoding/json"
    "os"

    "github.com/apex/log"
    "github.com/apex/log/handlers/text"
)

func main() {
    logger := text.New(os.Stdout)
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        text := scanner.Text()
        e := log.Entry{}
        if err := json.Unmarshal([]byte(text), &e); err != nil {
            panic(err)
        }
        logger.HandleLog(&e)
    }

    if err := scanner.Err(); err != nil {
        panic(err)
    }
}

Add method for writing entire entries

If you are unmarshaling from JSON you can just pass it to the handler, but if you don't have direct access to the handler we need another method for that.

Change trace duration to milliseconds

I think nanoseconds is far too much granularity for the average use-case, I've never had a problem with millisecond resolution, but it's a breaking change.

Tags

Currently this project has no tagged releases, making vendoring harder than it should be.

When to call function close in graylog handler?

Hi, I am really interested in apex/log because of its built in handler to support many different logger and services. However, I don't see an example for using graylog handler. I tried to implement it myself and it works (perfectly). However, I wonder there is a Close function in the handler and I don't know when to call it?

func (h *Handler) Close() error {

Can you provide a full example of using graylog handler and specify using of Close function.

Best regards,

errors implementing fielder?

This might be a dumb idea, so feel free to kick me out :P


I think it will be very handy to check if a given error implements Fielder in WithError() and add its .Fields() to the returned context.

package main

import "github.com/apex/log"

type ValidationError struct {
	message string              // holds a general validation error
	errors  map[string][]string // a map of `field => errors`
}

func (ve ValidationError) Error() string {
	return ve.message
}

func (ve ValidationError) Fields() log.Fields {
	ret := make(log.Fields, len(ve.errors))

	for field, errs := range ve.errors {
		ret[field] = errs
	}

	return ret
}

func validate() error {
	return &ValidationError{
		message: "validation error",
		errors: map[string][]string{
			"type": []string{
				"type must be one of foo/baz/woot",
				"type is required",
			},
		},
	}
}

func main() {
	err := validate()
	if err != nil {
		log.WithError(err).Fatal("validation error")
	}
}

So output with a Fielder check would be:

  ~ go run /tmp/test.go 
2017/04/11 23:33:46 fatal validation error          error=validation error type=[type must be one of foo/baz/woot type is required]
exit status 1

Inherent design problem with HandleLog function

Problem:
It is allowed by the developer to construct a Entry struct (field are public), but you supply no way to submit the entry to a handler correctly using the HandleLog function.

How?
The Entry struct requires to be finalized, which can only be obtained using the private, which is only called here:

log/logger.go

Line 146 in ff0f669

if err := l.Handler.HandleLog(e.finalize(level, msg)); err != nil {
This leaves the developer forced to use the public methods of the Logger struct, which does not support the HandleLog function

Why?
Sometimes the developer may want to have complete control of the logging (e.g. setting the log level of the entry dynamically)

Possible solutions:

  • Make the finalize function public
  • Wrap all HandleLog functions and call finalize beforehand
  • Add HandleLog to the Logger struct and call finalize
  • Create a wrapper handler which only job is to finalize the entry

You are probably more suited to find a proper solution yourself. Your thoughts?

Add level filtering handler

So you can have multiple, but only log certain levels to Elasticsearch etc. Basically: levels.New(otherHandler, log.ErrorLevel)

Question: Not printing line number on error

Hi I ran the tracing sample but it was not printing the line number. This is my current output.

INFO[0001] opening                   app=myapp env=prod path=Readme.md
 ERROR[0001] opening                   app=myapp duration=22.987µs env=prod error=open Readme.md: no such file or directory path=Readme.md
  INFO[0002] opening                   app=myapp env=prod path=Readme.md
 ERROR[0002] opening                   app=myapp duration=8.866µs env=prod error=open Readme.md: no such file or directory path=Readme.md

My code is (taken from the tracing examlple)

package main

import (
	"os"
	"time"

	"github.com/apex/log"
	"github.com/apex/log/handlers/text"
)

func work(ctx log.Interface) (err error) {
	path := "Readme.md"
	defer ctx.WithField("path", path).Trace("opening").Stop(&err)
	_, err = os.Open(path)
	return
}

func main() {
	log.SetHandler(text.New(os.Stderr))

	ctx := log.WithFields(log.Fields{
		"app": "myapp",
		"env": "prod",
	})

	for range time.Tick(time.Second) {
		_ = work(ctx)
	}
}

go version go1.8.3 darwin/amd64

Error in delta handler example

The delta handler example can be found here.

# github.com/apex/log/handlers/delta
../workspace/src/github.com/apex/log/handlers/delta/delta.go:140: time.Since(h.start).Round undefined (type time.Duration has no field or method Round)
../workspace/src/github.com/apex/log/handlers/delta/delta.go:142: time.Since(h.start).Round undefined (type time.Duration has no field or method Round)

Getting nil pointer references when log.SetHandler(...) is not set

Is there anyway to prevent this? I'd love to use this library more like debug (logging within nested packages), seems like the default should be discard.

Definitely down to open a PR with a bit of direction :-)

Looks like this:

panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x1d053c]

goroutine 5 [running]:
panic(0x283620, 0xc42000c0d0)
	/usr/local/Cellar/go/1.7.4_1/libexec/src/runtime/panic.go:500 +0x1a1
testing.tRunner.func1(0xc420094180)
	/usr/local/Cellar/go/1.7.4_1/libexec/src/testing/testing.go:579 +0x25d
panic(0x283620, 0xc42000c0d0)
	/usr/local/Cellar/go/1.7.4_1/libexec/src/runtime/panic.go:458 +0x243
github.com/apex/log.(*Logger).log(0xc420010200, 0x1, 0xc420105988, 0xc420018be0, 0x9e)
	/Users/matt/go/src/github.com/apex/log/logger.go:125 +0x6c
github.com/apex/log.(*Entry).Info(0xc420105988, 0xc420018be0, 0x9e)
	/Users/matt/go/src/github.com/apex/log/entry.go:61 +0x50
github.com/apex/log.(*Logger).Info(0xc420010200, 0xc420018be0, 0x9e)
	/Users/matt/go/src/github.com/apex/log/logger.go:68 +0x7f
github.com/apex/log.Info(0xc420018be0, 0x9e)
	/Users/matt/go/src/github.com/apex/log/pkg.go:44 +0x49

WithCaller depth is fixed

If this package needs to be wrapped (say for grpclog.Logger compatibility) the hardcoded depth is a bit a nuisance.

Need variadic

Will apex/log support api like log.Debug(args ...interface{})?

For now, I can only pass a string to log functions, sometimes it's not very convenience.

json handler: Unsupported type serializing oauth error

One of the errors dispatched by the oauth2 library contains a http.Response which causes the following error:

error logging: json: unsupported type: func() (io.ReadCloser, error)

This feels like something WithError(err) should handle gracefully, otherwise knowledge of underlying error types needs to be propagated throughout the code.

I'm happy to submit a patch, but not sure what the best solution for this is. Guidance welcome.

Add caller (file:line number) to non-tracing entries?

Any opinions on this? It's available from runtime.Caller. Following the current design, it could be enabled by having a function like log.IncludeCaller(bool) and then every entry would include a field caller with value file:line number). Could also implement this as the default log library handles flags, e.g. log.SetFlags(log.LstdFlags | log.Lshortfile).

I'm happy to create a PR for this if you'd like.

fatal error: concurrent map iteration and map write

We experienced a crash today that I'm having trouble diagnosing. The error occurred when calling logger.Info inside a goroutine. There were several parallel tasks, all which log when they complete. This code has been running, unchanged for months and I don't believe we've had any issues before.

Are logger.WithField and logger.WithError intended to be threadsafe?

Thanks in advance.


The error occurs at line 155 in (e *Entry) mergedFields

151	func (e *Entry) mergedFields() Fields {
152		f := Fields{}
153	
154		for _, fields := range e.fields {
155			for k, v := range fields {
156				f[k] = v
157			}
158		}
159
160		return f
161	}
/usr/lib/golang/src/runtime/panic.go:617 +0x72 fp=0xc001167d48 sp=0xc001167d18 pc=0x43a112
runtime.mapiternext(0xc001167e28)
/usr/lib/golang/src/runtime/map.go:860 +0x597 fp=0xc001167dd0 sp=0xc001167d48 pc=0x41ccd7
vendor/github.com/apex/log.(*Entry).mergedFields(0xc00017d260, 0x14)
/go/src/vendor/github.com/apex/log/entry.go:155 +0x6c fp=0xc001167e98 sp=0xc001167dd0 pc=0x77aeac
vendor/github.com/apex/log.(*Entry).finalize(0xc00017d260, 0x1, 0x1779ed3, 0x1c, 0x0)
/go/src/vendor/github.com/apex/log/entry.go:167 +0x2f fp=0xc001167ee0 sp=0xc001167e98 pc=0x77afef
vendor/github.com/apex/log.(*Logger).log(0x2978830, 0x1, 0xc00017d260, 0x1779ed3, 0x1c)
/go/src/vendor/github.com/apex/log/logger.go:146 +0x5c fp=0xc001167f28 sp=0xc001167ee0 pc=0x77c31c
vendor/github.com/apex/log.(*Entry).Info(...)

Global logger without race conditions

Hi, first off I love the ideas behind apex and apex/log. I wanted to use apex/log in a package of mine, so to use it in multiple files I ended up doing this:

// logger.go
var Logger *alog.Entry

func init() {
    alog.SetHandler(text.New(os.Stderr))
    if ios.Getenv("DEBUG") != "" {
        alog.SetLevel(alog.DebugLevel)
    }
    Logger = alog.WithField("program", "super-downloader")
}

And within the other files I could use it like so:

// downloader.go
Logger.Debug("Downloading " + v.ID)
Logger.Debug("Download started 200 OK")

This worked great until I ran my tests which use t.Parallel() with DEBUG=true resulting in race conditions and the following errors:

=================
WARNING: DATA RACE
Write by goroutine 10:
 DEBUG[0000] getting video metadata     github.com/apex/log.(*Logger).log()
      /Users/montanaflynn/Development/go/src/github.com/apex/log/logger.go:126 +0x8d
  github.com/apex/log.(*Entry).Debug()
      /Users/montanaflynn/Development/go/src/github.com/apex/log/entry.go:57 +0x61
  github.com/montanaflynn/downloader.NewVideo()
      github.com/montanaflynn/downloader/_test/_obj_test/video.go:17 +0x9f
  github.com/montanaflynn/downloader.TestDownload()
      /Users/montanaflynn/Development/go/src/github.com/montanaflynn/downloader/download_test.go:7 +0x81
  testing.tRunner()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:456 +0xdc

Previous write by goroutine 12:
  github.com/apex/log.(*Logger).log()
      /Users/montanaflynn/Development/go/src/github.com/apex/log/logger.go:126 +0x8d
  github.com/apex/log.(*Entry).Debug()
      /Users/montanaflynn/Development/go/src/github.com/apex/log/entry.go:57 +0x61
  github.com/montanaflynn/downloader.NewVideo()
      github.com/montanaflynn/downloader/_test/_obj_test/video.go:17 +0x9f
  github.com/montanaflynn/downloader.TestFallback()
      /Users/montanaflynn/Development/go/src/github.com/montanaflynn/downloader/fallback_test.go:7 +0x81
  testing.tRunner()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:456 +0xdc
 program=super-downloader
Goroutine 10 (running) created at:
  testing.RunTests()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:561 +0xaa3
  testing.(*M).Run()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:494 +0xe4
  main.main()
      github.com/montanaflynn/downloader/_test/_testmain.go:124 +0x384

Goroutine 12 (running) created at:
  testing.RunTests()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:561 +0xaa3
  testing.(*M).Run()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:494 +0xe4

  main.main()
      github.com/montanaflynn/downloader/_test/_testmain.go:124 +0x384
==================
==================
WARNING: DATA RACE
Write by goroutine 10:
  github.com/apex/log.(*Logger).log()
      /Users/montanaflynn/Development/go/src/github.com/apex/log/logger.go:127 +0xaf
  github.com/apex/log.(*Entry).Debug()
      /Users/montanaflynn/Development/go/src/github.com/apex/log/entry.go:57 +0x61
  github.com/montanaflynn/downloader.NewVideo()
      github.com/montanaflynn/downloader/_test/_obj_test/video.go:17 +0x9f
  github.com/montanaflynn/downloader.TestDownload()
      /Users/montanaflynn/Development/go/src/github.com/montanaflynn/downloader/download_test.go:7 +0x81
  testing.tRunner()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:456 +0xdc

Previous write by goroutine 12:
  github.com/apex/log.(*Logger).log()
      /Users/montanaflynn/Development/go/src/github.com/apex/log/logger.go:127 +0xaf
  github.com/apex/log.(*Entry).Debug()
      /Users/montanaflynn/Development/go/src/github.com/apex/log/entry.go:57 +0x61
  github.com/montanaflynn/downloader.NewVideo()
      github.com/montanaflynn/downloader/_test/_obj_test/video.go:17 +0x9f
  github.com/montanaflynn/downloader.TestFallback()
      /Users/montanaflynn/Development/go/src/github.com/montanaflynn/downloader/fallback_test.go:7 +0x81
  testing.tRunner()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:456 +0xdc

Goroutine 10 (running) created at:
  testing.RunTests()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:561 +0xaa3
  testing.(*M).Run()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:494 +0xe4
  main.main()
      github.com/montanaflynn/downloader/_test/_testmain.go:124 +0x384

Goroutine 12 (running) created at:
  testing.RunTests()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:561 +0xaa3
  testing.(*M).Run()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:494 +0xe4
  main.main()
      github.com/montanaflynn/downloader/_test/_testmain.go:124 +0x384
==================
==================
WARNING: DATA RACE
Write by goroutine 10:
  github.com/apex/log.(*Logger).log()
      /Users/montanaflynn/Development/go/src/github.com/apex/log/logger.go:128 +0x124
  github.com/apex/log.(*Entry).Debug()
      /Users/montanaflynn/Development/go/src/github.com/apex/log/entry.go:57 +0x61
  github.com/montanaflynn/downloader.NewVideo()
      github.com/montanaflynn/downloader/_test/_obj_test/video.go:17 +0x9f
  github.com/montanaflynn/downloader.TestDownload()
      /Users/montanaflynn/Development/go/src/github.com/montanaflynn/downloader/download_test.go:7 +0x81
  testing.tRunner()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:456 +0xdc

Previous write by goroutine 12:
  github.com/apex/log.(*Logger).log()
      /Users/montanaflynn/Development/go/src/github.com/apex/log/logger.go:128 +0x124
  github.com/apex/log.(*Entry).Debug()
      /Users/montanaflynn/Development/go/src/github.com/apex/log/entry.go:57 +0x61
  github.com/montanaflynn/downloader.NewVideo()
      github.com/montanaflynn/downloader/_test/_obj_test/video.go:17 +0x9f
  github.com/montanaflynn/downloader.TestFallback()
      /Users/montanaflynn/Development/go/src/github.com/montanaflynn/downloader/fallback_test.go:7 +0x81
  testing.tRunner()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:456 +0xdc

Goroutine 10 (running) created at:
  testing.RunTests()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:561 +0xaa3
  testing.(*M).Run()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:494 +0xe4
  main.main()
      github.com/montanaflynn/downloader/_test/_testmain.go:124 +0x384

Goroutine 12 (running) created at:
  testing.RunTests()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:561 +0xaa3
  testing.(*M).Run()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:494 +0xe4
  main.main()
      github.com/montanaflynn/downloader/_test/_testmain.go:124 +0x384
==================

Can you cut another release please

I would like to use your updates for Windows colored output, but I am using go mod and can't figure out how to pull from master and not v1.0.0.

kthxbye 😉

Add a Flush() to the interface?

This would require some updates, but it would help for handlers like papertrail and ES to have the ability to buffer, with a defer log.Flush(). For ones that go to stderr, it could be a no-op.

Implement the io.Writer interface?

Would make stuff like this a bit easier:

go io.Copy(log.Info, command.Stdout)
go io.Copy(log.Error, command.Stderr)

I guess it'd have to be something like else like:

go io.Copy(log.InfoWriter(), command.Stdout)
go io.Copy(log.ErrorWriter(), command.Stderr)

Debug(), Error() etc. should accept an interface instead of string

A lot of the times I want to simply pass in the error to Error() (or similar functions) which works on Sirupsen/logrus, but now that I am trying to switch to apex/log it breaks all those cases.

if err != nil {
  log.Error(err) // This is now broken
}

// Instead I have to do this
if err != nil {
  log.Errorf("%s", err) // or log.Error(err.Error()) which is not as clean
}

Stringify Duration field in Stop

Currently the duration field in log.Stop is set to be a time.Duration type, which is then formatted by the handlers. see here:

log/entry.go

Lines 144 to 146 in a0bcece

e.WithField("duration", time.Since(e.start)).Info(e.Message)
} else {
e.WithField("duration", time.Since(e.start)).WithError(*err).Error(e.Message)

With the JSON handler, this ends up looking like this:

"duration":1935807,

Calling .String() on the duration ends up with a more human-readable:

"duration":"1.935807ms"

I realize that the JSON handler is meant to be machine-parseable, but think the second is still machine-parseable while being much more human-readable.

Any thoughts? Would be glad to submit a PR with this change.

Not able to send to graylog

I have a function which I am calling to send data to graylog. But when I do it, it does not send it. It is working fine if I run it in main.go file but when I use it as a package it does not work.

package boot

func SendMessageToGraylog(fileName, functionName, message string, err error) {
	graylogHandler, err := graylog.New("udp://0.0.0.0:12201")
	if err != nil {
		fmt.Println("this is err", err.Error())
	}

	l := &log.Logger{
		Handler: graylogHandler,
		Level:   log.InfoLevel,
	}

	ctx := l.WithFields(log.Fields{
		"fileName":     fileName,
		"functionName": functionName,
		"message":      message,
	})

	for range time.Tick(time.Second * 2) {
		ctx.Info("Upload")
	}
}

When I call this function boot.SendMessageToGraylog it does not work. Would you please suggest what I am doing wrong? cc @tj . Thanks

Higher level for Lambda

Tiny wrapper around apex/log would be nice. Specifically to output using the "text" handler locally, and "json" handler in AWS Lambda so that those logs can be parsed and forwarded. We'd just need to inject LAMBDA=1 in the env or something that we can sniff.

sinks

Not really an issue specific to this repo, but once ready it'll need some documentation here. Idea is basically to recommend Kinesis here, and use one or more sinks which can be apex deploy'd. I haven't decided yet if this will be a single program with configuration for each sink or separate programs, the binaries get large pretty quick but we'll see. Ideally we just have a logstash that is not Ruby, chuck that in Lambda and yeah

Interface is broken

`⇒ go run cli.go

command-line-arguments

./cli.go:12: cannot use cli.Default (type cli.Handler) as type "github.com/apex/log".Handler in argument to "github.com/apex/log".SetHandler:
*cli.Handler does not implement "github.com/apex/log".Handler (wrong type for HandleLog method)
have HandleLog(
"github.com/apex/log/vendor/github.com/apex/log".Entry) error
want HandleLog(*"github.com/apex/log".Entry) error`

Have log.Fielder return a map[string]interface{} ?

Right now you can't implement a custom fielder without pulling in the apex/log library.

I'm not sure if this would be a breaking change or not, but it'd be nice to change:

type Fielder interface {
	Fields() Fields
}

to this:

type Fielder interface {
	Fields() map[string]interface{}
}

When using json handler, it report that PANIC: reflect: call of reflect.Value.MapKeys on ptr Value

Exactly, i love apex/log, i use it in many project.

But recently in a high load project, i report an odd bug PANIC: reflect: call of reflect.Value.MapKeys on ptr Value, it a little challenging .

line 48 | log.WithFields(log.Fields{
	    		"Method": r.Method,
	    		"Body":   reqBodyStr,
	    		"API":    r.URL.Path,
line 52 | }).Info("LoggerMiddleware")

Bug trace

/usr/lib/golang/src/encoding/json/encode.go:333 +0x82
encoding/json.(*encodeState).marshal(0xc0000c62c0, 0x807320, 0xc0001300e0, 0x7f0e582c0100, 0x0, 0x0)
	/usr/lib/golang/src/encoding/json/encode.go:305 +0xf4
encoding/json.(*Encoder).Encode(0xc000132230, 0x807320, 0xc0001300e0, 0x9acb6116ee30, 0xc0001b01e0)
	/usr/lib/golang/src/encoding/json/stream.go:200 +0x8a
gitlab.ucloudadmin.com/UserProduct/ukms-svc/vendor/github.com/apex/log/handlers/json.(*Handler).HandleLog(0xc00011a210, 0xc0001300e0, 0x0, 0x0)
	/root/kai.wang/go/src/gitlab.ucloudadmin.com/UserProduct/ukms-svc/vendor/github.com/apex/log/handlers/json/json.go:33 +0x8f
gitlab.ucloudadmin.com/UserProduct/ukms-svc/vendor/github.com/apex/log.(*Logger).log(0xcf1500, 0x1, 0xc000130070, 0x823089, 0x10)
	/root/kai.wang/go/src/gitlab.ucloudadmin.com/UserProduct/ukms-svc/vendor/github.com/apex/log/logger.go:146 +0x7f
gitlab.ucloudadmin.com/UserProduct/ukms-svc/vendor/github.com/apex/log.(*Entry).Info(0xc000130070, 0x823089, 0x10)
	/root/kai.wang/go/src/gitlab.ucloudadmin.com/UserProduct/ukms-svc/vendor/github.com/apex/log/entry.go:86 +0x50
gitlab.ucloudadmin.com/UserProduct/ukms-svc/middleware.Logger.func1(0x7f0e5822d080, 0xc00011e018, 0xc000126100, 0xc000280040)
	/root/kai.wang/go/src/gitlab.ucloudadmin.com/UserProduct/ukms-svc/middleware/logger.go:52 +0x37c
gitlab.ucloudadmin.com/UserProduct/ukms-svc/vendor/github.com/urfave/negroni.HandlerFunc.ServeHTTP(0x840698, 0x7f0e5822d080, 0xc00011e018, 0xc000126100, 0xc000280040)

Can you help me solve it ? or give me some tips ?

Thank you so much, my idol.

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.