Esempio n. 1
0
// New creates a gelf logger using the configuration passed in on the
// context. Supported context configuration variables are
// gelf-address, & gelf-tag.
func New(ctx logger.Context) (logger.Logger, error) {
	// parse gelf address
	address, err := parseAddress(ctx.Config["gelf-address"])
	if err != nil {
		return nil, err
	}

	// collect extra data for GELF message
	hostname, err := ctx.Hostname()
	if err != nil {
		return nil, fmt.Errorf("gelf: cannot access hostname to set source field")
	}

	// remove trailing slash from container name
	containerName := bytes.TrimLeft([]byte(ctx.ContainerName), "/")

	// parse log tag
	tag, err := loggerutils.ParseLogTag(ctx, "")
	if err != nil {
		return nil, err
	}

	extra := map[string]interface{}{
		"_container_id":   ctx.ContainerID,
		"_container_name": string(containerName),
		"_image_id":       ctx.ContainerImageID,
		"_image_name":     ctx.ContainerImageName,
		"_command":        ctx.Command(),
		"_tag":            tag,
		"_created":        ctx.ContainerCreated,
	}

	extraAttrs := ctx.ExtraAttributes(func(key string) string {
		if key[0] == '_' {
			return key
		}
		return "_" + key
	})
	for k, v := range extraAttrs {
		extra[k] = v
	}

	// create new gelfWriter
	gelfWriter, err := gelf.NewWriter(address)
	if err != nil {
		return nil, fmt.Errorf("gelf: cannot connect to GELF endpoint: %s %v", address, err)
	}

	return &gelfLogger{
		writer:   gelfWriter,
		ctx:      ctx,
		hostname: hostname,
		extra:    extra,
	}, nil
}
Esempio n. 2
0
// New creates a gelf logger using the configuration passed in on the
// context. Supported context configuration variables are
// gelf-address, & gelf-tag.
func New(ctx logger.Context) (logger.Logger, error) {
	// parse gelf address
	address, err := parseAddress(ctx.Config["gelf-address"])
	if err != nil {
		return nil, err
	}

	// collect extra data for GELF message
	hostname, err := ctx.Hostname()
	if err != nil {
		return nil, fmt.Errorf("gelf: cannot access hostname to set source field")
	}

	// remove trailing slash from container name
	containerName := bytes.TrimLeft([]byte(ctx.ContainerName), "/")

	// parse log tag
	tag, err := loggerutils.ParseLogTag(ctx, "")
	if err != nil {
		return nil, err
	}

	fields := gelfFields{
		hostname:      hostname,
		containerID:   ctx.ContainerID,
		containerName: string(containerName),
		imageID:       ctx.ContainerImageID,
		imageName:     ctx.ContainerImageName,
		command:       ctx.Command(),
		tag:           tag,
		created:       ctx.ContainerCreated,
	}

	// create new gelfWriter
	gelfWriter, err := gelf.NewWriter(address)
	if err != nil {
		return nil, fmt.Errorf("gelf: cannot connect to GELF endpoint: %s %v", address, err)
	}

	return &gelfLogger{
		writer: gelfWriter,
		ctx:    ctx,
		fields: fields,
	}, nil
}
Esempio n. 3
0
// New creates a graylog2 hook
func New(address, facility string, extra map[string]interface{}, level logrus.Level) (logrus.Hook, error) {
	w, err := gelf.NewWriter(address)
	if err != nil {
		return nil, err
	}

	hostname, err := hostname()
	if err != nil {
		return nil, err
	}

	return &Hook{
		levels:   levelThreshold(level),
		w:        w,
		hostname: hostname,
		facility: facility,
		extra:    extra,
	}, err
}
Esempio n. 4
0
// New creates a gelf logger using the configuration passed in on the
// context. The supported context configuration variable is gelf-address.
func New(ctx logger.Context) (logger.Logger, error) {
	// parse gelf address
	address, err := parseAddress(ctx.Config["gelf-address"])
	if err != nil {
		return nil, err
	}

	// collect extra data for GELF message
	hostname, err := ctx.Hostname()
	if err != nil {
		return nil, fmt.Errorf("gelf: cannot access hostname to set source field")
	}

	// parse log tag
	tag, err := loggerutils.ParseLogTag(ctx, loggerutils.DefaultTemplate)
	if err != nil {
		return nil, err
	}

	extra := map[string]interface{}{
		"_container_id":   ctx.ContainerID,
		"_container_name": ctx.Name(),
		"_image_id":       ctx.ContainerImageID,
		"_image_name":     ctx.ContainerImageName,
		"_command":        ctx.Command(),
		"_tag":            tag,
		"_created":        ctx.ContainerCreated,
	}

	extraAttrs := ctx.ExtraAttributes(func(key string) string {
		if key[0] == '_' {
			return key
		}
		return "_" + key
	})
	for k, v := range extraAttrs {
		extra[k] = v
	}

	rawExtra, err := json.Marshal(extra)
	if err != nil {
		return nil, err
	}

	// create new gelfWriter
	gelfWriter, err := gelf.NewWriter(address)
	if err != nil {
		return nil, fmt.Errorf("gelf: cannot connect to GELF endpoint: %s %v", address, err)
	}

	if v, ok := ctx.Config["gelf-compression-type"]; ok {
		switch v {
		case "gzip":
			gelfWriter.CompressionType = gelf.CompressGzip
		case "zlib":
			gelfWriter.CompressionType = gelf.CompressZlib
		case "none":
			gelfWriter.CompressionType = gelf.CompressNone
		default:
			return nil, fmt.Errorf("gelf: invalid compression type %q", v)
		}
	}

	if v, ok := ctx.Config["gelf-compression-level"]; ok {
		val, err := strconv.Atoi(v)
		if err != nil {
			return nil, fmt.Errorf("gelf: invalid compression level %s, err %v", v, err)
		}
		gelfWriter.CompressionLevel = val
	}

	return &gelfLogger{
		writer:   gelfWriter,
		ctx:      ctx,
		hostname: hostname,
		rawExtra: rawExtra,
	}, nil
}
Esempio n. 5
0
func sendGelf() {
	r, w := io.Pipe()
	stdoutWriter := bufio.NewWriter(os.Stdout)
	gelfWriter, err := gelf.NewWriter(config.address)
	if err != nil && config.debug {
		log.Printf("Can not create GELF connection: %s", err)
	}

	/* combine STDIN and STDERR into one io.Pipe */
	go func(writer io.Writer) {
		stdinReader := bufio.NewReader(os.Stdin)
		for true {
			line, err := stdinReader.ReadString('\n')
			if err != nil {
				time.Sleep(300 * time.Millisecond)
			} else {
				writer.Write([]byte(line))
			}
		}
	}(w)
	go func(writer io.Writer) {
		stderrReader := bufio.NewReader(os.Stderr)
		for true {
			line, err := stderrReader.ReadString('\n')
			if err != nil {
				time.Sleep(300 * time.Millisecond)
			} else {
				writer.Write([]byte(line))
			}
		}
	}(w)
	reader := bufio.NewReader(r)

	/* send every log line as GELF message */
	for true {
		line, err := reader.ReadString('\n')
		if err != nil {
			/* No data could be read from STDIN/STDERR */
			time.Sleep(300 * time.Millisecond)
			continue
		}

		/* additionally print log line back to STDOUT */
		if config.echo == true {
			_, err = stdoutWriter.WriteString(string(line))
			if err != nil && config.debug {
				log.Printf("Failed to write log message to STDOUT: %s", err)
			}
			err = stdoutWriter.Flush()
			if err != nil && config.debug {
				log.Printf("Failed to flush STDOUT buffer: %s", err)
			}
		}

		extraFields := make(map[string]interface{})
		if len(config.tag) == 2 {
			extraFields[getExtraFieldName(config.tag[0])] = config.tag[1]
		}

		m := gelf.Message{
			Version:  "1.1",
			Host:     config.source,
			Short:    string(line),
			TimeUnix: float64(time.Now().UnixNano()/int64(time.Millisecond)) / 1000.0,
			Level:    6,
			Facility: config.facility,
			Extra:    extraFields,
		}

		if err := gelfWriter.WriteMessage(&m); err != nil && config.debug {
			log.Printf("gelf: cannot send GELF message: %v", err)
		}
	}

	gelfWriter.Close()
}