Advertisement
Guest User

Logstash Config

a guest
Apr 5th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.61 KB | None | 0 0
  1. input {
  2. beats {
  3. id => "api_beats"
  4. client_inactivity_timeout => 1200
  5. port => 11000
  6. }
  7. }
  8.  
  9. filter {
  10. # Tag event based on its document type
  11. if [fields][document_type] == "requests" {
  12. mutate {
  13. add_tag => [ "apiRequestEvent" ]
  14. remove_field => [ "[fields][document_type]" ]
  15. }
  16. } else if [fields][document_type] == "errors" {
  17. mutate {
  18. add_tag => [ "errorEvent" ]
  19. remove_field => [ "[fields][document_type]" ]
  20. }
  21. } else if [fields][document_type] == "soaprequests" {
  22. mutate {
  23. add_tag => [ "soapRequestEvent" ]
  24. remove_field => [ "[fields][document_type]" ]
  25. }
  26. } else {
  27. mutate {
  28. add_tag => [ "unknownEvent" ]
  29. }
  30. }
  31.  
  32. # Ensure the fields.environment field exists
  33. # as this field is used to push event to correct index
  34. if ![fields][environment] {
  35. mutate {
  36. add_field => { "[fields][environment]" => "unknown" }
  37. }
  38. } else if [fields][environment] == "" {
  39. mutate {
  40. add_field => { "[fields][environment]" => "unknown" }
  41. }
  42. }
  43.  
  44. # Perform api request message parsing
  45. if "apiRequestEvent" in [tags] {
  46. grok {
  47. id => "apiRequestParsing"
  48. match => { "message" => "%{TIMESTAMP_ISO8601:RequestTime}\t%{DATE:RequestDate}\t%{DATA:APIKey}\t%{DATA:APIMethod}\t%{DATA:RequestUrl}\t%{DATA:RequestBody}\t%{DATA:WidgetID}\t%{INT:ElapsedMilliseconds}\t%{DATA:ClientIP}\t%{DATA:OtherFields}\t%{GREEDYDATA:MachineName}" }
  49. remove_field => [ "RequestDate", "message" ]
  50. tag_on_failure => [ "_grokparsefailure", "apiRequestParsingFailure" ]
  51. }
  52.  
  53. # Parse RequestUrl field into its relevant pieces
  54. if [RequestUrl] =~ /.+/ {
  55. grok {
  56. id => "apiRequestUrlParsing"
  57. match => { "RequestUrl" => "%{GREEDYDATA:RequestUrl_Root}\?%{GREEDYDATA:RequestUrl_QueryString}" }
  58. tag_on_failure => [ "_grokparsefailure", "requestUrlParsingFailure" ]
  59. }
  60.  
  61. kv {
  62. source => "RequestUrl_QueryString"
  63. field_split => "&"
  64. prefix => "RequestUrl_"
  65. transform_key => "lowercase"
  66. include_keys => [ "format", "mnetid", "trackid" ]
  67. }
  68.  
  69. mutate {
  70. rename => { "RequestUrl_format" => "RequestUrl_Format" }
  71. rename => { "RequestUrl_mnetid" => "RequestUrl_MnetID" }
  72. rename => { "RequestUrl_trackid" => "RequestUrl_MnetID" }
  73. }
  74.  
  75. kv {
  76. source => "RequestUrl_QueryString"
  77. field_split => "&"
  78. prefix => "RequestUrl_QueryString_"
  79. transform_key => "lowercase"
  80. }
  81. }
  82.  
  83. # Parse OtherFields field into its relevant pieces
  84. if [OtherFields] =~ /.+/ {
  85. kv {
  86. source => "OtherFields"
  87. field_split => ";"
  88. prefix => "OtherFields_"
  89. include_keys => [ "HttpMethod", "PartnerName" ]
  90. }
  91.  
  92. mutate {
  93. rename => { "OtherFields_HttpMethod" => "RequestUrl_HttpMethod" }
  94. rename => { "OtherFields_PartnerName" => "PartnerName" }
  95. }
  96.  
  97. # Backfill APIKey as PartnerName when PartnerName is not present
  98. if ![PartnerName] {
  99. mutate {
  100. copy => { "APIKey" => "PartnerName" }
  101. }
  102. }
  103. }
  104.  
  105. # Lowercase APIMethod field to resolve mixed casing issues
  106. mutate {
  107. lowercase => [ "APIMethod" ]
  108. }
  109. }
  110.  
  111. # Perform soap request message parsing
  112. if "soapRequestEvent" in [tags] {
  113. # grok doesn't seem to go past \n so convert to EOL first
  114. mutate {
  115. gsub => [ "message", "\n", "EOL" ]
  116. }
  117.  
  118. grok {
  119. id => "soapRequestParsing"
  120. match => { "message" => "----- SoapRequest at %{DATESTAMP:RequestTime} to %{URI:RequestURL}(?<Line1>.*)EOL(?<RequestXML>.*)EOL----- SoapResponse at %{DATESTAMP:ResponseTime}(?<Line3>.*)EOL(?<ResponseXML>.*)EOL" }
  121. remove_field => [ "Line1", "Line3", "message" ]
  122. tag_on_failure => [ "_grokparsefailure", "soapRequestParsingFailure" ]
  123. }
  124.  
  125. # Save host as MachineName as its not included in message
  126. mutate {
  127. copy => { "host" => "MachineName" }
  128. }
  129. }
  130.  
  131. # Perform error message parsing
  132. if "errorEvent" in [tags] {
  133. grok {
  134. id => "errorParsing"
  135. match => { "message" => "%{TIMESTAMP_ISO8601:RequestTime}\t%{DATE:RequestDate}\t%{DATA:APIKey}\t%{DATA:APIService}\t%{WORD:APIServiceMethod}\t%{DATA:ErrorMessage}\t%{GREEDYDATA:StackTrace}\t%{INT:ErrorCode}\t%{IP:ClientIP}\t%{GREEDYDATA:MachineName}" }
  136. remove_field => [ "RequestDate", "message" ]
  137. tag_on_failure => [ "_grokparsefailure", "errorParsingFailure" ]
  138. }
  139. }
  140.  
  141. # Remove unused default event fields
  142. mutate {
  143. remove_field => [ "host", "input_type", "offset", "type" ]
  144. }
  145.  
  146. # Save current timestamp as ProcessedTimestamp only if there wasn't a grok parse failure
  147. if "_grokparsefailure" not in [tags] and "unknownEvent" not in [tags] {
  148. mutate {
  149. rename => { "@timestamp" => "ProcessedTimestamp" }
  150. }
  151. }
  152.  
  153. # Set RequestTime as new timestamp and its own RequestTimestamp field
  154. if [RequestTime] =~ /.+/ {
  155. date {
  156. match => [ "RequestTime", "yyyy-MM-dd HH:mm:ss", "MM-dd-yyyy HH:mm:ss.SSS" ]
  157. timezone => "US/Pacific"
  158. target => "@timestamp"
  159. }
  160.  
  161. date {
  162. match => [ "RequestTime", "yyyy-MM-dd HH:mm:ss", "MM-dd-yyyy HH:mm:ss.SSS" ]
  163. timezone => "US/Pacific"
  164. target => "RequestTimestamp"
  165. remove_field => [ "RequestTime" ]
  166. }
  167. }
  168.  
  169. # Set ResponseTime as its own ResponseTimestamp field
  170. if [ResponseTime] =~ /.+/ {
  171. date {
  172. match => [ "ResponseTime", "MM-dd-yyyy HH:mm:ss.SSS" ]
  173. timezone => "US/Pacific"
  174. target => "ResponseTimestamp"
  175. remove_field => [ "ResponseTime" ]
  176. }
  177.  
  178. # Calculate elapsed time
  179. ruby {
  180. code => 'event.set("RequestDuration", event.get("ResponseTimestamp") - event.get("RequestTimestamp"))'
  181. }
  182. }
  183.  
  184. # Perform ClientIP lookup
  185. if [ClientIP] =~ /.+/ {
  186. geoip {
  187. source => "ClientIP"
  188. }
  189. }
  190. }
  191.  
  192. output {
  193. # Change output index depending upon event tag
  194. if "apiRequestEvent" in [tags] {
  195. elasticsearch {
  196. hosts => [ "localhost:9200" ]
  197. id => "api-requests_elasticsearch"
  198. index => "api-%{[fields][environment]}-apirequests_write"
  199. template_name => "api"
  200. }
  201. } else if "soapRequestEvent" in [tags] {
  202. elasticsearch {
  203. hosts => [ "localhost:9200" ]
  204. id => "api-soaprequests_elasticsearch"
  205. index => "api-%{[fields][environment]}-soaprequests_write"
  206. template_name => "api"
  207. }
  208. } else {
  209. # Submit errorEvents and unknownEvents to same index
  210. elasticsearch {
  211. hosts => [ "localhost:9200" ]
  212. id => "api-errors_elasticsearch"
  213. index => "api-%{[fields][environment]}-errors_write"
  214. template_name => "api"
  215. }
  216. }
  217. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement