This function allows to choose one out of two expressions based on a condition. It provides a functionality similar to the ... ? ... : ... operator known from some programming languages.

Unlike a case or match statement, the if() can be embedded into other functions and expressions.

ParameterTypeRequiredDefaultDescription
asstringoptional[a]_if The name of the output destination field.
condition[b]expressionrequired  The conditional expression to evaluate.
elseexpressionrequired  The alternative statement to execute.
thenexpressionrequired  The consequent statement to execute.

[a] Optional parameters use their default value unless explicitly set

[b] The argument name condition can be omitted.

Omitted Argument Names

The argument name for condition can be omitted; the following forms of this function are equivalent:

logscale
if("value",else="value",then="value")

and:

logscale
if(condition="value",else="value",then="value")

These examples show basic structure only; full examples are provided below.

The behavior of:

logscale
if(cond, then=onTrue, else=onFalse, as=y)

is equivalent to a case expression:

logscale
case {
  test(cond) | y := onTrue;
  y := onFalse
}

In particular:

  • The interpretation of condition is the same as the expression argument of test().

  • The evaluation of then / else arguments is the same as the evaluation of the right-hand side of :=.

The if() function:

  • is a simplified version of the case / match based alternative.

  • can be used as an expression inside other expressions.

if() Examples

Add a Field based on Values of Another Field

Query
flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 0{Conditional} result{{Result Set}} repo --> 0 0 --> result
logscale
| statusClass :=
if(regex("^1", field=statuscode), then="informational", else=
if(regex("^2", field=statuscode), then="successful", else=
if(regex("^3", field=statuscode), then="redirection", else=
if(regex("^4", field=statuscode), then="client error", else=
if(regex("^5", field=statuscode), then="server error", else=
"unknown")))))
Introduction

Nested if() functions can be used within a larger expression for adding a field whose value is calculated based on another field.

Step-by-Step
  1. Starting with the source repository events

  2. flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 0{Conditional} result{{Result Set}} repo --> 0 0 --> result style 0 fill:#ff0000,stroke-width:4px,stroke:#000;

    Add a statusClass field where the following conditions are set:

    • If the value of field statuscode begins with 1, then statusClass is labeled as informational, otherwise:

    • If the value of field statuscode begins with 2, then statusClass is labeled as successful, otherwise:

    • If the value of field statuscode begins with 3, then statusClass is labeled as redirection, otherwise:

    • If the value of field statuscode begins with 4, then statusClass is labeled as client error, otherwise:

    • If the value of field statuscode begins with 5, then statusClass is labeled as server error, otherwise it is labeled as unknown.

    logscale
    | statusClass :=
    if(regex("^1", field=statuscode), then="informational", else=
    if(regex("^2", field=statuscode), then="successful", else=
    if(regex("^3", field=statuscode), then="redirection", else=
    if(regex("^4", field=statuscode), then="client error", else=
    if(regex("^5", field=statuscode), then="server error", else=
    "unknown")))))
  3. Event Result set

Summary and Results

Nested if() functions for tagging a field according to different statuscode values.

Convert Timestamps Based on Accuracy

Query
flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 0{Conditional} result{{Result Set}} repo --> 0 0 --> result
logscale
errortime := if((@ingesttimestamp > @timestamp), then=@timestamp, else=@ingesttimestamp) / 1000
Introduction

When parsing and processing data, the time of the data can be critical, and not all events include an explicit @timestamp field, but the ingest time stamp, when the event was parsed by LogScale, can be a suitable proxy. The lack of timestamp, or a significant difference between the timestamps may result in displaying an empty value (or creating an event stream that cannot be summarized in a graph).

Step-by-Step
  1. Starting with the source repository events

  2. flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 0{Conditional} result{{Result Set}} repo --> 0 0 --> result style 0 fill:#ff0000,stroke-width:4px,stroke:#000;

    The event field errortime is set to the latest time value, either timestamp or @ingesttimestamp.

    logscale
    errortime := if((@ingesttimestamp > @timestamp), then=@timestamp, else=@ingesttimestamp) / 1000
  3. Event Result set

Determine a Score Based on Field Value

Query
flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 0{{Aggregate}} 1{Conditional} result{{Result Set}} repo --> 0 0 --> 1 1 --> result
logscale
percentile(filesize, percentiles=[40,80],as=score)
| symbol := if(filesize > score_80, then=":+1:", else=if(filesize > score_40, then="so-so", else=":-1:"))
Introduction

When summarizing and displaying data, it may be necessary to derive a score or validity based on a test value. This can be achieved using if() by creating the score value if the underlying field is over a threshold value.

Step-by-Step
  1. Starting with the source repository events

  2. flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 0{{Aggregate}} 1{Conditional} result{{Result Set}} repo --> 0 0 --> 1 1 --> result style 0 fill:#ff0000,stroke-width:4px,stroke:#000;

    Calculate the percentile() for the filesize field and determine what filesize that is above 40% of the overall event set, and 80% of the overall event set.

    logscale
    percentile(filesize, percentiles=[40,80],as=score)
  3. flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 0{{Aggregate}} 1{Conditional} result{{Result Set}} repo --> 0 0 --> 1 1 --> result style 1 fill:#ff0000,stroke-width:4px,stroke:#000;

    Compare whether the filesize is greater than 80% of the events, setting symbol to :+1:. Because if() functions can be embedded, the else parameter is another if() statement that sets symbol to so-so if the size is greater than 40%, or :+1: otherwise.

    logscale
    | symbol := if(filesize > score_80, then=":+1:", else=if(filesize > score_40, then="so-so", else=":-1:"))
  4. Event Result set

Summary and Results

Using if() is the best way to make conditional choices about values. The function has the benefit of being able to be embedded into other statements, unlike case.

Set a Field Value Based on Tag Value

Query
flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 0{Conditional} result{{Result Set}} repo --> 0 0 --> result
logscale
keyprocess := if(#eventType == "Spawn", then=ChildID, else=ProcessID)
Introduction

When processing event data, there are occasions when a value needs to be determined from another field in the event. In this example, the field keyprocess is populated based on the #eventType tag.

Step-by-Step
  1. Starting with the source repository events

  2. flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 0{Conditional} result{{Result Set}} repo --> 0 0 --> result style 0 fill:#ff0000,stroke-width:4px,stroke:#000;

    Using the if(), set the value of keyprocess to the value of the ChildID if #eventType is Spawn; otherwise, set keyprocess to ProcessID.

    logscale
    keyprocess := if(#eventType == "Spawn", then=ChildID, else=ProcessID)
  3. Event Result set

Summary and Results

Using if() provides a simplified way of processing and parsing data when the test value can be easily identified.

In this example, the process ID has been identified based on whether it is the original or a spawn (child) process.

Use Multiple if() Functions

Query
flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 0{Conditional} result{{Result Set}} repo --> 0 0 --> result
logscale
score := if(x != "N/A", then=x, else=0) +  if(y != "N/A", then=y, else=0)
Introduction

Multiple if() functions can be used in a computation (eval/assign).

Step-by-Step
  1. Starting with the source repository events

  2. flowchart LR; %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% repo{{Events}} 0{Conditional} result{{Result Set}} repo --> 0 0 --> result style 0 fill:#ff0000,stroke-width:4px,stroke:#000;

    This computation checks if fields x or y is not a number, then 0 will be used instead.

    logscale
    score := if(x != "N/A", then=x, else=0) +  if(y != "N/A", then=y, else=0)
  3. Event Result set

Summary and Results

Setting the value based on an incoming value enables determination of a score triggered by a value.