Grok pattern conditionnel check

Problème

Lorsque l'ont veut appliquer un pattern grok sur une chaine envoyée par filebeat par exemple, il arrive que certains champs qui doivent respecter un pattern donné soit vide ce qui se traduit coté grok par un pattern qui ne correspond pas et donc par un parsing qui n'est pas envoyé correctement à elastic search. 

Exemple

Soit la chaine suivante : 
[27/Oct/2017:15:38:48 +0200] 127.0.0.1 - 200 80 212 GET /show HTTP/1.1

Et le pattern grock suivant : 
\[%{MONTHDAY}[./-]%{WORD}[./-]%{YEAR}[:]%{TIME}%{SPACE}[+]%{INT}\]%{SPACE}%{IP:[parameters][remoteip]}%{SPACE}%{USER:[parameters][user]}%{SPACE}%{INT:[parameters][httpcode]}%{SPACE}%{INT:[parameters][localport]}%{SPACE}%{INT:[parameters][processtime]}%{SPACE}%{GREEDYDATA:[parameters][requestfistline]}

Le résultat attendu :

{
  "MONTHDAY": [
    [
      "27"
    ]
  ],
  "WORD": [
    [
      "Oct"
    ]
  ],
  "YEAR": [
    [
      "2017"
    ]
  ],
  "TIME": [
    [
      "15:38:48"
    ]
  ],
  "HOUR": [
    [
      "15"
    ]
  ],
  "MINUTE": [
    [
      "38"
    ]
  ],
  "SECOND": [
    [
      "48"
    ]
  ],
  "SPACE": [
    [
      " ",
      " ",
      " ",
      " ",
      " ",
      " ",
      " "
    ]
  ],
  "INT": [
    [
      "0200"
    ]
  ],
  "[parameters][remoteip]": [
    [
      "127.0.0.1"
    ]
  ],
  "IPV6": [
    [
      null
    ]
  ],
  "IPV4": [
    [
      "127.0.0.1"
    ]
  ],
  "[parameters][user]": [
    [
      "-"
    ]
  ],
  "USERNAME": [
    [
      "-"
    ]
  ],
  "[parameters][httpcode]": [
    [
      "200"
    ]
  ],
  "[parameters][localport]": [
    [
      "80"
    ]
  ],
  "[parameters][processtime]": [
    [
      "212"
    ]
  ],
  "[parameters][requestfistline]": [
    [
      "GET /show HTTP/1.1"
    ]
  ]
}

Si dans la chaîne récupérée l'ip n’apparaît plus alors le pattern ne sera pas correspondant:
[27/Oct/2017:15:38:48 +0200]  - 200 80 212 GET /show HTTP/1.1

Solution

Utiliser le terme conditionnel pour la vérification du pattern.
Cela se traduit par l'utilisation de (?:le terme a mettre en conditionnel |).

Exemple : 

\[%{MONTHDAY}[./-]%{WORD}[./-]%{YEAR}[:]%{TIME}%{SPACE}[+]%{INT}\]%{SPACE}(?:%{IP:[parameters][remoteip]}|)%{SPACE}%{USER:[parameters][user]}%{SPACE}%{INT:[parameters][httpcode]}%{SPACE}%{INT:[parameters][localport]}%{SPACE}%{INT:[parameters][processtime]}%{SPACE}%{GREEDYDATA:[parameters][requestfistline]}

Maintenant le pattern est bien correspondant et la chaîne traitée correctement. 

Commentaires

Posts les plus consultés de ce blog

Insufficient privileges avec SonarQube 5.0 et Jenkins

Mettre en place le plugin OWASP dependency check dans les projets SONAR

Docker registry avec certificat auto-signé (--insecure-registry)