Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Environment Variable in conditionals #5115

Closed
githubmui opened this issue Apr 14, 2016 · 37 comments · Fixed by #13608
Closed

Support Environment Variable in conditionals #5115

githubmui opened this issue Apr 14, 2016 · 37 comments · Fixed by #13608

Comments

@githubmui
Copy link

Hi,
in LS 2.3.0. I have got the problem that following expression doesn't evaluate to TRUE (if environment variable doesn't exists).

if "${LS_ENDP_JDBC:a}" == "a" { ... }

Thx in advance for reply.

@suyograo
Copy link
Contributor

@githubmui The environment variable option was mostly added for substituting values, and not using it in conditional. But it seems this is a good usecase too. I'll keep this open as an enhancement.

@suyograo suyograo changed the title Problem with Environment Variable (LS 2.3.0)? Support Environment Variable in conditionals Apr 15, 2016
@githubmui
Copy link
Author

Hi,
its also an missing issue for the parameters of all the input plugins!
For example, it's not possible to use this nice feature for the URL of a "http_poller".

@IrlJidel
Copy link
Contributor

IrlJidel commented Apr 25, 2016

As a workaround you could use mutate and metadata fields

mutate {
  add_field => { "[@metadata][LS_ENDP_JDBC]" => "${LS_ENDP_JDBC:a}" }
}

if [@metadata][LS_ENDP_JDBC] == "a" {
...
}

@czerasz
Copy link

czerasz commented Jul 16, 2016

The usage in if would make the configs more generic:

output {
  if "${OUTPUT:elasticsearch}" == "debug" {
    stdout { codec => rubydebug }
  } else {
    elasticsearch { ... }
  }
}

@maya-sh
Copy link

maya-sh commented Jul 18, 2016

any update on this ? currently I am using the same approach as @IrlJidel, but it's more convenient to have the env. var. in the condition

@berglh
Copy link

berglh commented Dec 8, 2016

I also want conditional inputs based on comparisons with environmental variables:

LS_DEV_MODE=false ./logstash --debug -e '
input { 
  if "${LS_DEV_MODE}" == "false" { 
    file { path => "/tmp/file1" sincedb_path => "/dev/null" start_position => "beginning" } 
  } 
  if "${LS_DEV_MODE}" == "true" { 
    file { path => "/tmp/file2" sincedb_path => "/dev/null" start_position => "beginning" } 
  }
}
output { 
  stdout { codec => "rubydebug" } 
}'

This is because I wish to have development and production inputs in the one configuration stack and control the mode of the pipeline using LS_DEV_MODE=(true|false).

@maxlock
Copy link

maxlock commented Jan 24, 2017

+1 I also would like to change behaviour based upon environment variables.

@PhaedrusTheGreek
Copy link

+1 for being able to use environment variables in conditionals.

@astropuffin
Copy link

Was very surprised and sad to find that I couldn't do this. I would have thought that environment variables would substitute anywhere in the config on load. Really confused as to why this isn't the case.

@mrjameshamilton
Copy link

+1

@addykim
Copy link

addykim commented Feb 13, 2017

+1 although my desired use case is something like:

output {
    stdout { codec => rubydebug }
    if ${ELASTICSEARCH_HOST} is set {
        elasticsearch { 
            hosts => ["${ELASTICSEARCH_HOST}"]
            ...
        }
    }
}

Using psuedo code for the conditional because I'm not sure what the best way to check based on the current documentation, but that's a different topic.

@berglh
Copy link

berglh commented Feb 13, 2017 via email

@joniba
Copy link

joniba commented Feb 18, 2017

Can't get @IrlJidel 's workaround working on logstash 5.2.1. My conditionals are getting ignored. E.g., this always writes to localhost:9200:

input {
...
}

filter {
mutate {
add_field => { "[@metadata][ELASTIC_NOAUTH_URL]" => "${ELASTIC_NOAUTH_URL:x}" }
}
}

output {
if [@metadata][ELASTIC_NOAUTH_URL] != "x" {
elasticsearch {
hosts => [ "${ELASTIC_NOAUTH_URL:localhost:9200}" ]
}
}
}

I've tried miriad variations to no success :(

@danizen
Copy link

danizen commented Jun 8, 2017

+1 - just found this, and tried the other method first.

@nugend
Copy link

nugend commented Aug 4, 2017

Can elastic please call this out in documentation or put a warning for it at least? Got blocked for most of a day wondering what the hell I was doing wrong.

@mihomir
Copy link

mihomir commented Sep 5, 2017

+1
I've been debugging a Logstash configuration and the condition that should be used to identify the header in a CSV file is supposed to you environmental variables
if ["${COLUMN_NAME_USED_TO_SKIP_HEADER_ROW}"] == "${COLUMN_NAME_USED_TO_SKIP_HEADER_ROW}" {
And it appears that it is not working because of this issue.
Which is weird, when other parts of the Logstash configuration also use those variables and work as expected.

@berglh
Copy link

berglh commented Aug 9, 2018

Would be great to see this feature being worked on.

@duaraghav8
Copy link

Hi,
Has there been any progress on this issue?
Although it isn't a blocker for me, my workaround is pretty ugly and having this feature would make my pipeline configurations much more sane :)

@dormunis
Copy link

dormunis commented Oct 2, 2019

any progress?

@shubydo
Copy link

shubydo commented Jan 28, 2020

Any update on this issue? This is something we would really like to use in our pipelines.

@iTaybb
Copy link

iTaybb commented Mar 16, 2020

Can we please push this? It's a very useful feature that been requested for years.

@MorrieAtElastic
Copy link

I have a customer who opened a Support Ticket because his use of conditional logic on an env variable was being rejected as an error.

In fact this is a very desirable enhancement and the existing documentation, while not showing examples of using an ENV within a conditional statement, does not explicitly forbid such use.

@ceeeekay
Copy link

This is affecting me too. I just spent hours backtracking and making changes to my configs on a new build that's using a lot of variables.

Any progress on this?

@brunocascio
Copy link

brunocascio commented Sep 9, 2020

Anyone using env variables with conditionals?

I need something like this:

output {
  if "${IS_LOCAL}" == "true" {
    stdout {}
  } else {
    gelf {}
  }
}

@asmith-elastic
Copy link

There have been a few users that have expressed interest in this functionality, as this would be a desirable enhancement in order to satisfy their use cases.

+1 for being able to use environment variables in conditionals.

@Alexandre-Genon
Copy link

I'm also voting for this one, it will definitely be helpful to control the Logstash pipelines using environment variables.

@ay27
Copy link

ay27 commented Jun 11, 2021

any progress?

@makefu
Copy link

makefu commented Sep 10, 2021

I'd love to see this feature as well!

jsvd added a commit that referenced this issue Oct 7, 2021
Environment variable expansion only works in plugin parameters, not in conditionals.

For more on this limitation see #5115
jsvd added a commit that referenced this issue Oct 13, 2021
Environment variable expansion only works in plugin parameters, not in conditionals.
For more on this limitation see #5115
jsvd added a commit to jsvd/logstash that referenced this issue Oct 13, 2021
)

Environment variable expansion only works in plugin parameters, not in conditionals.
For more on this limitation see elastic#5115

(cherry picked from commit 096eb7a)
jsvd added a commit to jsvd/logstash that referenced this issue Oct 13, 2021
)

Environment variable expansion only works in plugin parameters, not in conditionals.
For more on this limitation see elastic#5115

(cherry picked from commit 096eb7a)
jsvd added a commit that referenced this issue Oct 13, 2021
…13311)

Environment variable expansion only works in plugin parameters, not in conditionals.
For more on this limitation see #5115

(cherry picked from commit 096eb7a)
jsvd added a commit that referenced this issue Oct 13, 2021
…13312)

Environment variable expansion only works in plugin parameters, not in conditionals.
For more on this limitation see #5115

(cherry picked from commit 096eb7a)
kaisecheng added a commit that referenced this issue Jan 25, 2022
This PR substitutes ${VAR} in Expression, except RegexValueExpression, with the value in secret store, env.
The substitution happens after syntax parsing and before graph execution.

Fixed: #5115
kaisecheng added a commit to kaisecheng/logstash that referenced this issue Jan 25, 2022
This PR substitutes ${VAR} in Expression, except RegexValueExpression, with the value in secret store, env.
The substitution happens after syntax parsing and before graph execution.

Fixed: elastic#5115
kaisecheng added a commit to kaisecheng/logstash that referenced this issue Jan 25, 2022
This PR substitutes ${VAR} in Expression, except RegexValueExpression, with the value in secret store, env.
The substitution happens after syntax parsing and before graph execution.

Fixed: elastic#5115
yaauie pushed a commit that referenced this issue Jan 26, 2022
This PR substitutes ${VAR} in Expression, except RegexValueExpression, with the value in secret store, env.
The substitution happens after syntax parsing and before graph execution.

Fixed: #5115
yaauie pushed a commit that referenced this issue Jan 26, 2022
This PR substitutes ${VAR} in Expression, except RegexValueExpression, with the value in secret store, env.
The substitution happens after syntax parsing and before graph execution.

Fixed: #5115
@kaisecheng
Copy link
Contributor

Logstash 7.17 has a fix for this issue

@brunobastosg
Copy link

brunobastosg commented May 24, 2022

Is it possible to use this feature to check if an environment variable is set?

Something like:

input {
  if "${BASE_URL}" {
    http_poller {
      urls => {
        url => "${BASE_URL}/api/v1"
      }
      request_timeout => 120
      socket_timeout => 60
      schedule => { cron => "0 7 * * *" }
      codec => "json"
    }
  }
}

I'm having trouble getting this to work.

@kaisecheng
Copy link
Contributor

@brunobastosg You can alternatively check by the following

if ("${VAR:}" != "") {
    http_poller { ... }
 }

You can give a default value by using the form ${VAR:default_value}. Logstash uses the default value if the environment variable is undefined.

@brunobastosg
Copy link

brunobastosg commented May 24, 2022

@kaisecheng does logstash still try to parse the http_poller block? Because after I tried your suggestion I got the following error:

[2022-05-24T17:42:23,751][INFO ][logstash.inputs.http_poller][main] Registering http_poller Input {:type=>"myType", :schedule=>{"cron"=>"* * * * *"}, :timeout=>nil}
[2022-05-24T17:42:24,151][ERROR][logstash.javapipeline    ][main] Pipeline error {:pipeline_id=>"main", :exception=>#<LogStash::ConfigurationError: Invalid URL /api/v1>, :backtrace=>["/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-input-http_poller-5.1.0/lib/logstash/inputs/http_poller.rb:142:in `validate_request!'", "/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-input-http_poller-5.1.0/lib/logstash/inputs/http_poller.rb:134:in `normalize_request'", "/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-input-http_poller-5.1.0/lib/logstash/inputs/http_poller.rb:65:in `block in setup_requests!'", "org/jruby/RubyHash.java:1415:in `each'", "org/jruby/RubyEnumerable.java:886:in `map'", "/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-input-http_poller-5.1.0/lib/logstash/inputs/http_poller.rb:65:in `setup_requests!'", "/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-input-http_poller-5.1.0/lib/logstash/inputs/http_poller.rb:55:in `register'", "/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-mixin-ecs_compatibility_support-1.3.0-java/lib/logstash/plugin_mixins/ecs_compatibility_support/target_check.rb:48:in `register'", "/usr/share/logstash/logstash-core/lib/logstash/java_pipeline.rb:232:in `block in register_plugins'", "org/jruby/RubyArray.java:1821:in `each'", "/usr/share/logstash/logstash-core/lib/logstash/java_pipeline.rb:231:in `register_plugins'", "/usr/share/logstash/logstash-core/lib/logstash/java_pipeline.rb:390:in `start_inputs'", "/usr/share/logstash/logstash-core/lib/logstash/java_pipeline.rb:315:in `start_workers'", "/usr/share/logstash/logstash-core/lib/logstash/java_pipeline.rb:189:in `run'", "/usr/share/logstash/logstash-core/lib/logstash/java_pipeline.rb:141:in `block in start'"], "pipeline.sources"=>["/usr/share/logstash/pipeline/logstash.conf"], :thread=>"#<Thread:0x2f63074d run>"}

Apparently it tried to validate the url ${BASE_URL:}/api/v1, but since BASE_URL is undefined, the url becomes /api/v1 which is not valid.

Here is the logstash.conf file:

input {
 # the http input is always available
  http {
    host => "0.0.0.0"
    port => 8080
  }
 # the http_poller input should only be available if BASE_URL is set
  if ("${BASE_URL:}" != "") {
    http_poller {
      urls => {
        url => "${BASE_URL:}/api/v1"
      }
      request_timeout => 120
      socket_timeout => 60
      schedule => { cron => "* * * * *" }
      codec => "json"
      type => "myType"
    }
  }
}

output {
  stdout { codec => rubydebug }
}

@kaisecheng
Copy link
Contributor

@brunobastosg if statement only works in filter { } and output { }

@brunobastosg
Copy link

@brunobastosg if statement only works in filter { } and output { }

Sorry, I hadn't noticed that in the documentation. I assumed it could be anywhere.

Thank you for your time!

@thom-vend
Copy link

FYI . VAR cannot be evaluated to a number, hence cannot do number comparison.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet