logspout
logspout copied to clipboard
Can't evaluate fields in template strings
Gentlemen, I started to have issues with format templates after I upgraded docker engine from 1.12 to 1.13.
Steps to reproducte
- I run a docker service using following command
docker service create --name logspout \
--network mejai-network \
--mode global \
--mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
--env SYSLOG_HOSTNAME='{{index .Config.Labels "com.docker.swarm.service.name"}}' \
--env SYSLOG_TAG='{{.Name}}' \
--env SYSLOG_STRUCTURED_DATA='cluster={{index .Config.Labels "ca.surrey.swarm.cluster"}}' \
gliderlabs/logspout $ELK
Actual result
Error response from daemon: rpc error: code = 3 desc = expanding env failed: expanding env "SYSLOG_HOSTNAME={{index .Config.Labels \"com.docker.swarm.service.name\"}}": template: expansion:1:15: executing "expansion" at <.Config.Labels>: can't evaluate field Config in type *template.Context
But if I run docker inspect --format {{.Config.Labels}} dda42680d044 it all works.
Any ideas?
Confirmed that this worked in docker 1.12. I fear this is a bit of chicken and egg where the labels aren't available in time. Not sure what we can reasonably do in logspout. Might be worth opening an issue against docker/docker?
docker 1.13 service inspect without env set:
"Labels": {
"com.docker.swarm.node.id": "10w0lr46p8q7d5mz2x97qxzkq",
"com.docker.swarm.service.id": "llu4uvhaqw282edlq1a90c7he",
"com.docker.swarm.service.name": "logspout",
"com.docker.swarm.task": "",
"com.docker.swarm.task.id": "dja3x17ac9e9v8xts27nmcgj8",
"com.docker.swarm.task.name": "logspout.1.dja3x17ac9e9v8xts27nmcgj8"
}
I'm having a similar issue trying to set {{.Service.Name}}-{{.Task.Slot}} as syslog tag on my stack/compose file.
logging:
driver: 'syslog'
options:
tag: '{{.Service.Name}}-{{.Task.Slot}}'
syslog-facility: 'local0'
suggestions?
Seems this have been solved on docker 17.10
did you test it? i'm still having issues.
failed to update service prod-swarm_logspout: Error response from daemon: rpc error: code = InvalidArgument desc = expanding env failed: expanding env "SYSLOG_STRUCTURED_DATA=BLABLA@41058 tag=\"bla\" {{ index .Container.Config.Labels \"net.bla.app.tags\" }}\n": template: expansion:1:42: executing "expansion" at <.Container.Config.La...>: can't evaluate field Container in type *template.Context
$ docker -v
Docker version 17.10.0-ce, build f4ffd25
docker 17.10 cannot be used in production because contains some critical errors (that fixed in the 17.11, but again, it is edge release and another critical error maybe).
As a solution, I just forked this project and build own image. https://github.com/develar/logspout/commit/c9d3571cf596d3a0143ea2d8fc4abb2b50d0ba2b
Same problem
stack:
version: "3.3"
services:
# just-log:
# image: zhaoyao91/just-log
# environment:
# INTERVAL: 10000
logsout:
image: gliderlabs/logspout
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: raw+udp://localhost:55555
environment:
LOGSPOUT: ignore
ALLOW_TTY: "true"
RAW_FORMAT: "{{.Data}}\n"
error:
failed to update service test-log_logsout: Error response from daemon: rpc error: code = InvalidArgument desc = expanding env failed: expanding env "RAW_FORMAT={{.Data}}\n": template: expansion:1:2: executing "expansion" at <.Data>: can't evaluate field Data in type *template.Context
is there an update for this ? can we use template variables in any environment variables ?
context.go looks to be the file that drives what can be templated. Could this be extended to support additional configuration (e.g. Node.Labels)?
I hit same problem with the expression RAW_FORMAT: {{ index .Config.Labels "com.docker.swarm.service.name" }} Tested on Docker 19.03.6
After many attempts found that you have to wrap Go Template expressions in another pair of curly braces. I have no idea why this must be done, neither documentation states you have to do it. Below expression works and it returns service name RAW_FORMAT: "{{`{{ index .Container.Config.Labels \"com.docker.swarm.service.name\" }}`}}\n"