Sem ver você tentando padrões que não funcionaram, não posso comentar por que eles não funcionaram. Como você afirmou que o padrão que você forneceu corresponde ao servidor, eu modifiquei sua declaração um pouco e adicionei um pouco ao final para capturar o restante:
(?<timestamp>%{YEAR}[./]%{MONTHNUM}[./]%{MONTHDAY} %{TIME}) \[%{LOGLEVEL:severity}\] %{POSINT:pid}#%{NUMBER}: %{GREEDYDATA:errormessage},\ client: %{IP:client}, server: \$domain, request: \"%{WORD:method} %{URIPATH:path}\"
Observe que, após o seu GREEDYDATA, eu adicionei uma vírgula, como você provavelmente não deseja que em seus dados capturados, e suponho que sempre será usado antes da parte do cliente da mensagem. Eu suspeito que você teve problemas com $ domain, já que você precisa de um \ na frente do $ para escapar dele.
Por favor, note que enquanto isso funciona no debugger grok, eu suspeito que ele não irá no logstash, você precisará escapar de todos os seus espaços também, para que o logstash seja legal com o padrão (isto é, mudar cada instância "" para "\")
re. : A melhor rota seria usar se instruções para interceptar as diferentes variações de mensagens de log no nginx?
Não estou bem claro sobre o que você está perguntando, mas você pode colocar instruções if em torno do seu filtro, ou partes do filtro, como neste answer . Você pode fazer a mesma coisa usando tags, se conseguir descobrir uma maneira de marcá-las. Estas duas opções são provavelmente "melhores" em termos de poder de processamento usado para cada linha, pois acredito que haverá menos trabalho envolvido do que algo como isto answer , pois cada evento precisaria ser verificado em relação a cada padrão. Você também pode escrever um padrão muito complexo que poderia corresponder a todas as situações diferentes, mas eu não acho que isso seja ideal, já que o padrão se expandirá para ter tantas combinações potenciais diferentes que precisaria de muito poder para checar a cada vez.
Espero que ajude!