I'm trying to use message formatting in slack. The Elastalert Testrule.yaml file is partially being parsed. The slack alert shows up with only slack_alert_fields and alert_text fields. I want to send attachments as well in the alerts.
How to use attachments or create buttons fort slack alerts?
es_host: elasticsearch
es_port: 9200
name: Test rule Alert
type: any
index: alerts-*
filter:
- term:
alertType.keyword: "New alert created"
alert:
- "slack"
slack_alert_fields:
- title: Network Name
value: networkName
short: true
- title: Alert Type
value: alertType
short: true
slack_actions:
- name: "network url"
text: "Network URL"
type: "button"
value: networkUrl
alert_text: |
alertData : {0}
alert_text_type: alert_text_only
alert_text_args: ["alertData"]
attachments: [
{
"fallback": "Required plain-text summary of the attachment.",
"color": "#37964f",
"pretext": "New alert created",
"title": alertData.reason ,
"fields": [
{
"title": "Network Name",
"value": networkName,
"short" : true
},
{
"title": "Timestamp",
"value": timestamp,
"short" : true
}
],
"actions": [
{
"name": "network url",
"text": "Network URL",
"type": "button",
"value": networkUrl
},
{
"name": "org_url",
"text": "Organization URL",
"type": "button",
"value": organizationUrl
}
]
}
]
slack_webhook_url:
- "https://hooks.slack.com/xxxxxxxxxxxxxxxxxxxxxxx"
Looking at the official documentation it appears that Elastalert does not support adding custom Slack attachments for alerts, because there is no property for it in the documentation.
In fact it seams that alerts are already formatted as attachment, which is why you can set a title and a title-URL. And also define additional "fields". Something that you can only do with attachments in Slack.
This also means that you can not specify buttons for your alerts (which are a special kind of attachments in Slack).
If you need this functionality I would suggest contacting the developer of Elastalert.
I have written a custom wireshark dissector using Lua that successfully dissects packets as expected when it is installed.
When I attempt to 'Export Packet Dissections' 'As JSON', however, all of the fields handled by my custom dissector are exported as follows:
"_ws.lua.text": ""
Here is a broader snippet:
"_ws.lua.fake": "",
"my_protocol": {
"_ws.lua.text": {
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": ""
},
"_ws.lua.text": {
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": "",
"_ws.lua.text": ""
},
"_ws.lua.text": ""
What do I need to do to get the fields handled by my custom dissector to be exported properly?
I had the same problem. I adjusted the dissectors and thus got rid of the "_ws.lua.text"s, but not the fakes. My dissector used to look like this:
my_proto=Proto("my_proto", "My custom Protocol", "My custom Protocol")
*something something*
local my_proto_packet = tree:add(my_proto, buffer(),"My custom protocol");
value = buffer(curPos,4):uint();
local valueNode = my_proto_packet:add_le(buffer(curPos, 4), "value = " .. value)
The "value = 3.8"-String was displayed in Wireshark.
I added a ProtoField-variable and added it into the proto.fields-array. And then changed the valueNode definition so it now looks like this:
my_proto=Proto("my_proto", "My custom Protocol", "My custom Protocol")
local field_myproto_intfield = ProtoField.uint32("myproto.intfield", "Integer", base.DEC)
my_proto.fields = { field_myproto_intfield }
local my_proto_packet = tree:add(my_proto, buffer(),"My custom protocol");
*something something*
valueNode:add(field_myproto_intfield, buffer(curPos, 4))
In my rails controller I'm getting JSON posted to it that contains a person's work history. So they could have multiple jobs. The jobs are in a format like...
"values":
[
{
"title": "dummy position",
"company": "company 1",
"location": "Indianapolis, IN",
"description": "dummy job description",
"startDateMonth": "05",
"startDateYear": "2015",
"endDateMonth": "06",
"endDateYear": "2015"
},
{
"title": "dummy position 2",
"company": "company 2",
"location": "Indianapolis, IN",
"description": "dummy job description 2",
"startDateMonth": "02",
"startDateYear": "2015",
"endDateMonth": "05",
"endDateYear": "2015"
},
{
"title": "dummy position 3",
"company": "company 3",
"location": "Indianapolis, IN",
"description": "dummy job description 3",
"startDateMonth": "05",
"startDateYear": "2013",
"endDateMonth": "02",
"endDateYear": "2015"
}
]
I'm trying to add these to the params collection that I can later iterate through in an application class and add these work histories. I have the following code but it doesn't work - NoMethodError - undefined method `[]' for nil:NilClass: for this line params[:job_title][i] = jobs[i]['title']. It was just a guess, as I'm not great in ruby, so is there a way to make this work?
if job_count.numeric?
jobs = params['positions']['values']
for i in 0..job_count.to_i
params[:job_title][i] = jobs[i]['title']
params[:job_company_name][i] = jobs[i]['company']
params[:job_start_date][i] = jobs[i]['startDateMonth'] + '/1/' + jobs[i]['startDateYear']
params[:job_end_date][i] = jobs[i]['endDateMonth'] + '/1/' + jobs[i]['endDateYear']
params[:job_description][i] = jobs[i]['description']
end
end
EDIT: This ended up working.
i = 0
jobs.each do | k, work_history |
i = i + 1
params['job_title_' + i.to_s] = work_history['title']
params['job_company_name_' + i.to_s] = work_history['company']
params['job_start_date_' + i.to_s] = work_history['startDateMonth'] + '/1/' + work_history['startDateYear']
params['job_end_date_' + i.to_s] = work_history['endDateMonth'] + '/1/' + work_history['endDateYear']
params['job_description_' + i.to_s] = work_history['description']
end
You get this error because you're trying to do ["title"] on nil, as said, and jobs[i] is probably nil because job_count is wrong.
If you have 3 jobs, and job_count == 3, your for loop will do 0, 1, 2, 3. However, jobs[3] is rightfully nil.
Try replacing that for with for i in 0..(job_count.to_i - 1)
I have read through all relevant posts on Prawn but found no mentioning (even in Prawn's own documentation) of headers and footers.
However, I did see a demo on Prawnto's own website about headers and footers. I copied the entire source of that demo just to see if it works but an error of undefined method "header" is complained about. Am I to understand that Prawn took out header and footer recently in the gem or is there something else I need to do first to use header and footer?
The demo page:
http://cracklabs.com/prawnto/code/prawn_demos/source/text/flowing_text_with_header_and_footer
the part of code of concern:
Prawn::Document.generate("flow_with_headers_and_footers.pdf") do
header margin_box.top_left do
text "Here's My Fancy Header", :size => 25, :align => :center
end
text "hello world!"
end
And by header, just in case, I mean the snippets of words that appear usually at a corner of every page of a document. Like your account number in your bills pages.
thanks!
The sample you are refering to, from the prawnto plugin, is using an older version of prawn.
Since i also needed header and footer i looked a bit more into this. It seems that that version of prawn had header and footer methods, which were implemented using lazy bounding box. (found by checking the code on github)
In the new prawn version you can do the same thing using repeaters.
Here is the full sample rewritten using the new version:
require "#{File.dirname(__FILE__)}/../example_helper.rb"
Prawn::Document.generate("test.pdf") do
repeat :all do
# header
bounding_box [bounds.left, bounds.top], :width => bounds.width do
font "Helvetica"
text "Here's My Fancy Header", :align => :center, :size => 25
stroke_horizontal_rule
end
# footer
bounding_box [bounds.left, bounds.bottom + 25], :width => bounds.width do
font "Helvetica"
stroke_horizontal_rule
move_down(5)
text "And here's a sexy footer", :size => 16
end
end
bounding_box([bounds.left, bounds.top - 50], :width => bounds.width, :height => bounds.height - 100) do
text "this is some flowing text " * 200
move_down(20)
font "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf"
table [["ὕαλον ϕαγεῖν", "baaar", "1" ],
["This is","a sample", "2" ],
["Table", "dont\ncha\nknow?", "3" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules\nwith an iron fist", "x" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ]],
:font_size => 24,
:horizontal_padding => 10,
:vertical_padding => 3,
:border_width => 2,
:position => :center,
:headers => ["Column A","Column B","#"]
end
end
you can check the documentation page of repeat for other options which allow you to exactly specify where you want the repeaters.
#GrantSayer thx for the example, but this will only let you show the current page number, not the total number of pages.
You can also use the number_pages function for the footer:
Prawn::Document.generate("page_with_numbering.pdf") do
text "Hai"
start_new_page
text "bai"
start_new_page
text "-- Hai again"
number_pages "<page> in a total of <total>", [bounds.right - 50, 0]
end
However, in my case I also need to format/style and right align the page numbers to match company style guides. I used go_to_page(k) to create my own header and footer functions, which add the header and footer to each page after all the pages are created. This gives me both styling options and the total number of pages:
Prawn::Document.generate("footer_example.pdf", :skip_page_creation => true) do
10.times do
start_new_page
text "Some filler text for the page"
end
# footer
page_count.times do |i|
go_to_page(i+1)
lazy_bounding_box([bounds.right-50, bounds.bottom + 25], :width => 50) {
text "#{i+1} / #{page_count}"
}.draw
end
end
It's little bit different with latest version of Prawn you must passe an hash
Prawn::Document.generate("page_with_numbering.pdf") do
text "Hai"
start_new_page
text "bai"
start_new_page
text "-- Hai again"
number_pages "<page> in a total of <total>", { :start_count_at => 0, :page_filter => :all, :at => [bounds.right - 50, 0], :align => :right, :size => 14 }
end
If you want a footer that do not write stuff over your text, you have to create the bounding_box below the margin of the document using bounds.bottom.
require 'prawn'
file_name = 'hello.pdf'
random_table = (0..50).map{|i|[*('a'..'z')]} # generate a 2D array for example (~2 pages)
Prawn::Document::generate(file_name) do |pdf|
pdf.table random_table
pdf.page_count.times do |i|
pdf.bounding_box([pdf.bounds.left, pdf.bounds.bottom], :width => pdf.bounds.width, :height => 30) {
# for each page, count the page number and write it
pdf.go_to_page i+1
pdf.move_down 5 # move below the document margin
pdf.text "#{i+1}/#{pdf.page_count}", :align => :center # write the page number and the total page count
}
end
end
It should look like that, you can see that the footer is outside the margin bottom :
Hope it help someone
START EDIT
This works in prawn >= 0.12
END EDIT
Here is my solution using repeat, canvas and cell. Essentially I'm drawing my bounding boxes at the absolute top and bottom of every page. I'm using cell to have better styling control over it. Hope this is going to be helpful to someone. ( I used slightly annoying colors to better illustrate how you can control styling of header and footer)
Prawn::Document.generate("headers_and_footers_with_background.pdf") do
repeat :all do
# header
canvas do
bounding_box([bounds.left, bounds.top], :width => bounds.width) do
cell :content => 'Header',
:background_color => 'EEEEEE',
:width => bounds.width,
:height => 50,
:align => :center,
:text_color => "001B76",
:borders => [:bottom],
:border_width => 2,
:border_color => '00FF00',
:padding => 12
end
end
# footer
canvas do
bounding_box [bounds.left, bounds.bottom + 50], :width => bounds.width do
cell :content => 'Footer',
:background_color => '333333',
:width => bounds.width,
:height => 50,
:align => :center,
:text_color => "FFFFFF",
:borders => [:top],
:border_width => 2,
:border_color => 'FF0000',
:padding => 12
end
end
end
# body
bounding_box([bounds.left, bounds.top - 25], :width => bounds.width, :height => bounds.height - 50) do
100.times do
text "Some filler text for the page"
end
end
end
here's the problem when using the bounding_box for creating the custom footer contents... it is still rendering within the bounds of a margin.
I was looking for something that will write the contents in the margin area together with number_pages.(because a footer usually is set in the bottom margin area)... and it seems that there were none.
so instead, I used text_box and place the coordinates outside my main bounding box like so:
repeat :all do
text_box "My custom footer", size: 7, align: :center, :at => [bounds.left, bounds.bottom], :height => 100, :width => bounds.width
end
take note that the repeat :all , will render this footer text to every page.
The only way I've found to get a repeating item on a page is to use the Prawn::Document::LazyBoundingBox method. Basically this allows you to define a bounding box that is only rendered once you call it. So the usual pseudo-code steps are
Define lazy bounding box element assign to somevar
On each new page call the element.
The example from the source shows how
file = "lazy_bounding_boxes.pdf"
Prawn::Document.generate(file, :skip_page_creation => true) do
point = [bounds.right-50, bounds.bottom + 25]
page_counter = lazy_bounding_box(point, :width => 50) do
text "Page: #{page_count}"
end
10.times do
start_new_page
text "Some filler text for the page"
page_counter.draw
end
end
This gives you a Page-count text output on each new page. What would be ideal is if this could be applied in the setup of a page template that is reused without the manual call to render the element. Combined with text flow this would give the traditional solution of headers and footers.