Rsyslog: how to negate 'contains' in if-then statement - rsyslog

if $programname == "service" then {
if $msg !contains "test" then
action(type="omfwd"
target="10.0.0.5"
...
)
}
I'm trying to exclude a msg if it contains word 'test'. Not sure how to negate 'contains'.
From the document, it seems to be '!contains'. Tried it but no luck.
Any idea?

The syntax ! for negation applies to legacy selectors of the form
:msg, !contains, "test" /some/file
You are using RainerScript, so the appropriate syntax is the keyword not:
if not ($msg contains "test") then

Related

Using multiple Conditions in Intellij Debugger Breakpoint

I want to add multiple conditions to a breakpoint in IntelliJ.
Something like:
stringA.equals("test") && objectA.equals(objectB);
How can I do this?
IntelliJ IDEA breakpoint condition can be any boolean expression:
Select to specify a condition for hitting a breakpoint. A condition is
a Java Boolean expression including a method returning true or false,
for example, str1.equals(str2).
This expression must be valid at the line where the breakpoint is set,
and it is evaluated each time the breakpoint is hit. If the evaluation
result is true, the selected actions are performed.
You can enter multi-line expressions, for example:
if (myvar == expectedVariable) {
System.out.println(myvar);
anotherVariable = true;
}
return true;
stringA.equals("test") && objectA.equals(objectB) appears to be a valid expression returning true or false, so it should work right out of the box.
Proof of work:
The following condition statement will also work:
return stringA.equals("test") && objectA.equals(objectB);
Please note that there is a known issue which will show a red underline after the condition indicating that semicolon is expected. If you add the semicolon, the condition will become invalid and you will have to also add a return statement to make it valid again. It's a cosmetic issue and you can either use the condition without semicolon and ignore the error or you can add the semicolon and return to make it a valid statement:
So adding a return statment in front of the statment solved the problem.

FuncOne() -and FuncTwo() not working

This is my code:
if (FuncOne($valOne) -and FuncTwo($valTwo)) {
...
}
When both of those functions evaluate to $false, the code within the if statement still executes. Why is that? This also does not work as expected:
if (FuncOne($valOne) -eq $true -and FuncTwo($valTwo) -eq $true) {
...
}
When written this way, it works as expected.
$a = FuncOne($valOne)
$b = FuncTwo($valTwo)
if($a -and $b) {
...
}
What's going on?
This is a syntax issue.
The correct syntax for invoking functions in PowerShell is not:
functionName($arg1[,$arg2,$arg3])
but rather:
functionName [-parameterName1] $arg1 [[-parameterName2] $arg2]
Now, let's apply this to your if() sample expression:
FuncOne $valOne -and FuncTwo $valTwo
You'll notice that explicit parameter names (-ParameterName) and operators (-and) are completely indistinguishable - there's no way for the parser to tell whether -and is supposed to be interpreted as a parameter name or an operator. Additionally, the string literal FuncTwo can just as well be interpreted as a parameter argument, which is exactly what happens.
In order for the parser to know that you intend it to treat the expression as two separate expressions, force evaluation order with ():
if ((FuncOne $valOne) -and (FuncTwo $valTwo)) {
# They both returns a truthy value
}
You actualy need to place the function in parenthese in order to invoke it:
if ((FuncOne($valOne)) -and (FuncTwo($valTwo))) {
...
}

How to use default value when given an empty string in powershell function?

I would like to use the default value when given an empty string. I am hoping for something more elegant then having an if statement to check if $Var is empty, and setting it to a default. Anyone know if this can be achieved? Also need to support powershell version 2.0.
Below is a snippet of what I'm trying to accomplish. Given an empty string I would like it to print "Var: DEFAULT".
$ErrorActionPreference = "Stop"
function Test-Function(
[parameter( Mandatory = $true )][string] $Var = "DEFAULT"
) {
# If Mandatory is set to $true an error is thrown
# "Cannot bind argument to parameter 'password' because it is an empty string."
# When Mandatory is set to $false, $Var is an empty string rather than "DEFAULT"
Write-Host "Var: $Var"
}
$EmptyString = ""
Test-Function -Var $EmptyString
Var is an empty string because you are explicitly passing an empty string. Empty strings are still objects, not null. Your call to Test-Function -Var $EmptyString fails to give you the output you are looking for as you are equating an empty string and null which is false in .Net. Your statement that "When Mandatory is set to $false, $Var is an empty string rather than 'DEFAULT'" is correct as you did pass something, an empty string so the assignment of the value "DEFAULT" was never called.
You could remove the Mandatory=$true in which case your "Default" value is displayed when the parameter is not passed.
function Test-Function(
[parameter( Mandatory = $false )]
[string] $Var = "DEFAULT"
){
Write-Host "Var: $Var"
}
Test-Function
This generates Var: DEFAULT as expected.
Regardless of whether the parameter is mandatory or not, if you pass an empty string the assignment to $Var = "Default" is never reached as $Var has a value of '' which while empty is actually a string.
Test-Function ''
This generates Var: Which may look like wrong but it output the empty string you told it to.
If you want to allow a default value to be assigned when the parameter is not passed use the Mandatory=$false and assign a default value as I did above. If you want to test the value that was passed and assign a default value if it was an empty string you should do that in the begin block of your function.
function Test-Function(
[parameter( Mandatory = $false )]
[string] $Var = "DEFAULT"
){
begin{if([String]::IsNullOrWhiteSpace($Var)){$Var="DEFAULT"}}
process{Write-Host "Var: $Var"}
end{}
}
Test-Function
Test-Function ''
Test-Function 'SomeValue'
This generates the following which I believe to be what you expected:
Var: DEFAULT
Var: DEFAULT
Var: SomeValue
There is no elegant way to do that. At least there is not a built-in way to do so. You can just validate that the string is not null or empty:
function Test {
Param (
[ValidateNotNullOrEmpty()]
[String]
$String = 'DEFAULT'
)
Write-Host -Object "String: $String"
}
Use this inside your function:
If (!($var)) {$var = "DEFAULT"} #basically, if $var doesn't exist, create it
ps. I've just tested it with Mandatory = $false and it works as expected, no idea why it doesn't work for you, what does it do when mandatory = $false?

Logstash filter regular expression difference in JRuby and Ruby

The Logstash filter regular expression to parse our syslog stream is getting more and more complicated, which led me to write tests. I simply copied the structure of a Grok test in the main Logstash repository, modified it a bit, and ran it with bin/logstash rspec as explained here. After a few hours of fighting with the regular expression syntax, I found out that there is a difference in how modifier characters have to be escaped. Here is a simple test for a filter involving square brackets in the log message, which you have to escape in the filter regular expression:
require "test_utils"
require "logstash/filters/grok"
describe LogStash::Filters::Grok do
extend LogStash::RSpec
describe "Grok pattern difference" do
config <<-CONFIG
filter {
grok {
match => [ "message", '%{PROG:theprocess}(?<forgetthis>(: )?(\\[[\\d:|\\s\\w/]*\\])?:?)%{GREEDYDATA:message}' ]
add_field => { "process" => "%{theprocess}" "forget_this" => "%{forgetthis}" }
}
}
CONFIG
sample "uwsgi: [pid: 12345|app: 0|req: 21/93281] BLAHBLAH" do
insist { subject["tags"] }.nil?
insist { subject["process"] } == "uwsgi"
insist { subject["forget_this"] } == ": [pid: 12345|app: 0|req: 21/93281]"
insist { subject["message"] } == "BLAHBLAH"
end
end
end
Save this as e.g. grok_demo.rb and test it with bin/logstash rspec grok_demo.rb, and it will work. If you remove the double escapes in the regexp, though, it won't.
I wanted to try the same thing in straight Ruby, using the same regular expression library that Logstash uses, and followed the directions given here. The following test worked as expected, without the need for double escape:
require 'rubygems'
require 'grok-pure'
grok = Grok.new
grok.add_patterns_from_file("/Users/ulas/temp/grok_patterns.txt")
pattern = '%{PROG:theprocess}(?<forgetthis>(: )?(\[[\d:|\s\w/]*\])?:?)%{GREEDYDATA:message}'
grok.compile(pattern)
text1 = 'uwsgi: [pid: 12345|app: 0|req: 21/93281] BLAHBLAH'
puts grok.match(text1).captures()
I'm not a Ruby programmer, and am a bit lost as to what causes this difference. Is it possible that the heredoc config specification necessitates double escapes? Or does it have to do with the way the regular expression gets passed to the regexp library within Logstash?
I never worked with writing tests for logstash before, but my guess is the double escape is due to the fact that you have strings embedded in strings.
The section:
<<-CONFIG
# stuff here
CONFIG
Is a heredoc in ruby (which is a fancy way to generate a string). So the filter, grok, match, add and all the brackets/braces are actually part of the string. Inside this string, you are escaping the escape sequence so the resulting string has a single literal escape sequence. I'm guessing that this string gets eval'd somewhere so that all the filter etc. stuff gets implemented as needed and that's where the single escape sequence is getting used.
When using "straight ruby" you aren't doing this double interpretation. You're just passing a string directly into the method to compile it.

Word 2010 combining INCLUDEPICTURE and IF

Using MS Word 2010 I am trying to place an INCLUDEPICTURE field into a block of an IF statement. While both the IF statement and the INCLUDEPICTURE work correctly separate, they do not work in combination.
IF Statement:
{ IF { MERGEFIELD condition \* MERGEFORMAT } = "expression" "true" "false" \* MERGEFORMAT }
This works correctly.
INCLUDEPICTURE:
{ INCLUDEPICTURE "picture.png" }
This works correctly, too.
Combination of the two:
{ IF { MERGEFIELD condition \* MERGEFORMAT } = "expression" "{ INCLUDEPICTURE "picture.png" }" "false" \* MERGEFORMAT }
This does not work. If the IF expression is true, nothing is displayed at all.
How can I combine both the IF statement and the INCLUDEPICTURE command?
This is a well known-problem (i.e. you are right, it doesn't work).
Unfortunately, there isn't a particularly good solution - the simplest involves using a blank 1-pixel image file.
The usual starting point is to invert the nesting so that you have something more like this...
{ INCLUDEPICTURE "{ IF "{ MERGEFIELD condition }" = "expression" "picture.png" }" }" \d }
This always tries to insert a picture, and will report (and insert) an error in the case where { MERGEFIELD condition } <> "expression". The simplest resolution is to have a blank 1-pixel picture that you can include instead, e.g.
{ INCLUDEPICTURE "{ IF "{ MERGEFIELD condition }" = "expression" "picture.png" "blank1.png" }" }" \d }
It is sometimes clearer to remove the test and assignment and do it separately, particularly if there are multiple tests. In this case,
{ SET picname "{ IF "{ MERGEFIELD condition }" = "expression" "picture.png" "blank1.png" }" }
or if you prefer,
{ IF "{ MERGEFIELD condition }" = "expression" "{ SET picname "picture.png" }" "{ SET picname "blank1.png" }" }
You still need an IF nested inside the INNCLUDEPICTURE to make it work. You can use:
{ INCLUDEPICTURE "{ IF TRUE { picname } }" \d }
If you merge those nested fields to an output document, the fields will remain in the output. If you want the fields to be resolved (e.g. because you need to send the output to someone who does not have the image files) then you need something more like this:
{ IF { INCLUDEPICTURE "{ IF TRUE { picname } }" } { INCLUDEPICTURE "{ IF TRUE { picname } }" \d } }
I believe you can reduce this to
{ IF { INCLUDEPICTURE "{ picname }" } { INCLUDEPICTURE "{ IF TRUE { picname } }" \d } }
In fact, I believe you can insert the full path+name of any graphic file that you know exists instead of the first { picname }, e.g.
{ IF { INCLUDEPICTURE "the full pathname of blank1.png" } { INCLUDEPICTURE "{ IF TRUE { picname } }" \d } }
But you should check that those work for you.
EDIT
FWIW, some recent tests suggest that whereas the pictures appear unlinked, a save/re-open displays a reconstituted link (with a *MERGEFORMATINET near the end), and the pictures are expected to be at the locaitons indicated in those links. Whether this is due to a change in Word I cannot tell. If anything has changed, it looks to be an attempt to allow some relative path addressing in the Relationship records that Word creates inside the .docx.
Some observations...
Make sure paths have doubled-up backslashes, e.g.
c:\\mypath\\blank1.png . This is usually necessary for any paths
hard-coded into fields. For paths that come in via nested field
codes, please check.
As a general point, it is easier to work with INCLUDEPICTURE fields
when the document is a .doc, not .docx, and to ensure that
File->Options->Advanced->General->Web options->Files->"Update links
on save" is checked. Otherwise, Word is more likely to replace
INCLUDEPICTURE fields with a result that cannot be redisplayed as a
field using Alt-F9
When you want to treat the comparands in an IF field as strings, it
is advisable to surround them with double-quotes, as I have done.
Otherwise, a { MERGEFIELD } field that resolves to the name of a
bookmark may not behave as you would hope. Otherwise, spacing and
quoting is largely a matter of personal choice.
So far, none of these field constructions will deal with the situation where you have path names for pictures that may or may not exist. If that is what you need, please modify your original question.
Step by step guide:
bibadia's answer works, but word does not tell you when you make mistakes, so it is very hard to get it right. So I hope this step by step answer helps.
Step 1: Add a Picture
In Word 2013 docx (no idea about other versions) add
{ INCLUDEPICTURE "C:\\picture.png" }
Note: Use CTRL+F9 to add { } , don't ever type them in, as they will not work.
Use \\ and not \
Run the mail merge, do Ctrl+A then F9 to show the picture.
Step 2: Auto Show it
To change the mail merge document use (CTRL+A Shift+F9). Change it to
{ SET picname "C:\\picture.png" }
{ INCLUDEPICTURE "{ IF TRUE { picname } }" \d }
Run the mail merge - the picture should show up, no need for Ctrl+A then F9
Step 3: Unlink it
Remove the \d
This will let you email the doc. As the \d causes the document to create a link to the image file, rather than include it.
Step 4: add an IF
Use bibadia's solution, i.e.
{ SET picname "{ IF "{ MERGEFIELD condition }" = "expression" "picture.png" "blank1.png" }" }
Another option that I've tested works is to use an If statement to check an expression (In my example check if the entry is not null), and if not then display the image, if not display some custom text (If you don't want text just have empty quotation marks i.e. ""):
{IF {MERGEFIELD my_photo_variable_name} <> "" {INCLUDEPICTURE "{IF TRUE {MERGEFIELD my_photo_variable_name}}" \d} "Text to display if no picture available"}
Which translates as:
If there is no value for the image my_photo_variable_name, include the image in the mail merge.
If there is no value i.e no image, then display custom text Text to display if no picture available.

Resources