Bosun: Lookup is giving integer when string is expected - bosun

I'm tweaking my bosun.conf to allow my os.cpu.high alert to use a lookup when determining which duration to to use depending on the host:
lookup high_cpu {
entry host=* {
time = 5m
}
entry host=*graylog* {
time = 1h
}
}
alert os.cpu.high {
template = generic.graph
macro = host.based.contacts
$notes = Find CPU usage that is continually high
$duration = lookup("high_cpu", "time")
$host = *
$metric = "sum:rate{counter,,1}:os.cpu{host=$host}"
$q_cpu = q($metric, "$duration", "")
$q = avg($q_cpu)
warn = $q > 95
crit = $q > 99
ignoreUnknown = true
$q_format = %f
$unit_string = %
$generic_graph = $q_cpu
$graph_unit = %
}
This is the error I get when testing:
conf: Test Config:424:4: at <warn = $q > 95>: expr: unexpected "high" in func
I am not very familiar with bosun and this is probably an easy fix, but I'm at my wit's end. Any help would be appreciated

You can't do this, as lookups don't support a string return type.
This particular scenario would be problematic anyways since what you are trying to do is query different amount of times based on the result of the query, so you have a chicken and egg problem.
What you can do is query the max amount of time you want to query and then shorten some results in the set using the crop function. However the crop function is not in a release yet so you would have to get it in master. You can see the documentation with an example of what you are trying to do in this commit for now, i.e.:
lookup test {
entry host=ny-bosun01 {
start = 30
}
entry host=* {
start = 60
}
}
alert test {
template = test
$q = q("avg:rate:os.cpu{host=ny-bosun*}", "5m", "")
$c = crop($q, lookup("test", "start") , 0)
crit = avg($c)
}

Related

Groovy: Export Data - How to set unix start time from now to a certain point in the past?

I am currently exporting data from Grafana. I do that using a script which looks like this one:
JsonSlurper slurper = new JsonSlurper()
println "Collect list of servers:"
def result = slurper.parse(new URL('http://xyz'))
def servers = [:].withDefault { [] }
result.data.each{ it ->
servers[it.server] = "${it.server};${it.app};${it.team}"
}
servers.sort().each { k, v -> println v}
println "Collect data for servers:"
Date currentDate = new Date();
Date fromDate = currentDate - 30
long unixTimeNow = currentDate.getTime() / 1000
long unixFromDate = fromDate.getTime() / 1000
long stepSec = 7200
boolean header = true
servers.sort().each{ server, label ->
File resultFile = new File("C:\\Users\\GrafanaExport${server}.csv")
if(resultFile.exists()) {
resultFile.delete()
}
def queries = [
['node_load1',"http://abc{server}.start${unixFromDate}&end=${unixTimeNow}&step=${stepSec}"],]
def resultTable = [:].withDefault { [";",";",";"] }
queries.eachWithIndex { q, i ->
println(q)
result = slurper.parse(new URL(q[1]))
result?.data?.result[0]?.values?.each{ it ->
resultTable[it[0]][i] = it[1] + ";"
}
}
if(header) {
resultFile << "timestamp;" + queries.collect{it[0]}.join(';') + '\n'
header = false
}
resultFile << label + '\n'
resultTable.sort().each { k, v ->
resultFile << "${k};${v.join('')}\n"
}
}
This works fine but what I want to get instead is not the data from now until some time ago but from a certain timestamp until some time ago. Because previously I already exported data and I would like to get the same dates/timestamps for the data. The previously exported data is stamped with this timestamps (snip of the example timestamps):
That means the data was exported every two hours (because of this a step of 7200 seconds) and at every full and in unix time every even hour. I now want to know how I need to amend my code in order to get the data for the same timestamps as before?
Thanks a lot!

How to create a multi column table of data from the exponential distribution

I need to create a multi column table of customer arrival time, customer wait time, service time, and customer leave time. Service time is the time it takes for the cashier to help the customer. Arrival time and service time are provided by a function which uses the rexp command.
The table needs to look like this: table
My code looks like this:
singleTime = function(Rate)
{
data = rexp(1,Rate)
return(data)
}
waitTimes = function(m,arrivalRate,serviceRate)
{
arrivalTimes = c(1:m)
waitTimes = c(1:m)
serviceTimes = c(1:m)
leaveTimes = c(1:m)
previousLeaveTime = 0
for(i in (1:m))
{
arrivalTimes[i] = singleTime(arrivalRate)
if(i == 0)
{
waitTimes[i] = 0
}
else if((previousLeaveTime - arrivalTimes[i])<= 0)
{
waitTimes[i] = 0
}
else
{
waitTimes[i] = leaveTimes[i-1] - arrivalTimes[i]
}
serviceTimes[i] = singleTime(serviceRate)
leaveTimes[i] = waitTimes[i] + serviceTimes[i] + arrivalTimes[i]
previousLeaveTime = leaveTimes[i]
i = i + 1
}
waitTimesTable = table(arrivalTimes,waitTimes,serviceTimes,leaveTimes)
View(waitTimesTable)
}
Could you replace View(waitTimesTable) with return(data.frame(arrivalTimes, waitTimes, serviceTimes, leaveTimes)? I'm not sure how concerned you are with the look of the table.

web2py SQLFORM.grid url

When I try to put form = SQLFORM.grid(db.mytable) in my controller the request changes to my/web/site/view?_signature=520af19b1095db04dda2f1b6cbea3a03c3551e13 which causes my if statement in controller to collapse. Can smbd please explain why this happens?
If I put user_signature=False then on view load the grid is shown (though the looks is awful, and I still need to find out how to change the view of my table), but on search,edit, etc. click, the same thing happens again. The url is changed and I get an error
Any suggestions?
thank you
EDIT
This is my edit function
#auth.requires_login()
def edit():
#Load workers
workers = db(db.worker.w_organisation == 10).select(db.worker.w_id_w, db.worker.w_organisation, db.worker.w_first_name, db.worker.w_last_name,db.worker.w_nick_name,db.worker.w_email,db.worker.w_status,db.worker.w_note).as_list()
#Define the query object. Here we are pulling all contacts having date of birth less than 18 Nov 1990
query = ((db.worker.w_organisation == 10) & (db.worker.w_status==db.status.s_id_s))
#Define the fields to show on grid. Note: (you need to specify id field in fields section in 1.99.2
fields = (db.worker.w_first_name, db.worker.w_last_name,db.worker.w_nick_name,db.worker.w_email,db.status.s_code,db.worker.w_note)
#Define headers as tuples/dictionaries
headers = { 'worker.w_first_name' : 'Ime',
'worker.w_last_name' : 'Priimek',
'worker.w_nick_name' : 'Vzdevek',
'worker.w_email' : 'E-posta',
'status.s_code': 'Status',
'worker.w_note' : 'Komentar' }
#Let's specify a default sort order on date_of_birth column in grid
default_sort_order=[db.worker.w_last_name]
#Creating the grid object
form = SQLFORM.grid(query=query, fields=fields, headers=headers,searchable=True, orderby=default_sort_order,create=True, \
deletable=True, editable=True, maxtextlength=64, paginate=25,user_signature=False
)
form = SQLFORM.grid(db.worker,user_signature=False)
workersDb = db((db.worker.w_organisation == 10) & (db.worker.w_status==db.status.s_id_s)).select(db.worker.w_id_w, \
db.worker.w_organisation, db.worker.w_first_name, \
db.worker.w_last_name,db.worker.w_nick_name,db.worker.w_email,\
db.status.s_code,db.worker.w_note).as_list()
workersList = []
for rec in workersDb:
status = rec['status']['s_code']
workers = rec['worker']
if not rec["worker"]["w_first_name"]:
polno_ime = rec["worker"]["w_last_name"]
elif not rec["worker"]["w_last_name"]:
polno_ime = rec["worker"]["w_first_name"]
else:
polno_ime = rec["worker"]["w_first_name"] + " " + rec["worker"]["w_last_name"]
rec["worker"]['w_full_name'] = polno_ime
rec["worker"]["w_status"] = status
data = rec["worker"]
#print rec
#print data
workersList.append(rec["worker"])
# If type of arg is int, we know that user wants to edit a script with an id of the argument
if(request.args[0].isdigit()):
script = db(getDbScript(request.args[0])).select(db.script.sc_lls, db.script.sc_name, db.script.id, db.script.sc_menu_data).first()
formData = str(script["sc_menu_data"])
#form = SQLFORM.grid(db.auth_user)
#print formData
# If we dont get any results that means that user is not giving proper request and we show him error
#print script
#Parsing script to be inserted into view
if not script:
return error(0)
return dict(newScript = False, script = script, formData = formData, workers = workersList, form = form)
# If the argument is new we prepare page for new script
elif request.args[0] == 'new':
scripts = db((auth.user.organization == db.script.sc_organization)).select(db.script.sc_name, db.script.id, workers = workersList, form = form)
return dict(newScript = True, scripts = scripts, workers = workersList, form = form)
# Else error
else:
return error(0)
also not to mention the sqlgrid looks awful, here is link to the picture https://plus.google.com/103827646559093653557/posts/Bci4PCG4BQQ

Accessing SQL output in coding

I have a SQL output like
TotalLeave Status
---------- ------
3 PaidLeave
5 MedicalLave
and I need to show this value in my label controls like,
lblMedicalLeave.text = 5
lblPaidLeave.text = 3
for this I just created objects for my dataset in my code like,
StaffAttendanceStatusTableAdapters.StaffTypesTableAdapter staffAttendanceStatus =
new StaffAttendanceStatusTableAdapters.StaffTypesTableAdapter();
StaffAttendanceStatus.StaffTypesDataTable StaffDataTable =
staffAttendanceStatus.GetDataStaffAttendanceStatus(staff.StaffId);
if (StaffDataTable[0] != null)
{
StaffAttendanceStatus.StaffTypesRow StaffRow = StaffDataTable[0];
lblTotalMedicalLeave.Text = StaffRow.TotalLeave.ToString();
lblTotalPaidLeave.Text = StaffRow.TotalLeave.ToString();
}
its showing the same value(3), is it possible to get the TotalLeave value for corresponding Status? can anyone help me here
You are accessing the same row both times. Use StaffDataTable[1] to access the second row. Anyway you should check if there is a result before access any values!
using StaffAttendanceStatusTableAdapters;
....
StaffTypesTableAdapter staffAttendanceStatus = new StaffTypesTableAdapter();
StaffAttendanceStatus.StaffTypesDataTable StaffDataTable =
staffAttendanceStatus.GetDataStaffAttendanceStatus(staff.StaffId);
if (StaffDataTable != null && StaffDataTable.Count > 1)
{
lblTotalMedicalLeave.Text = StaffDataTable[0].TotalLeave.ToString();
lblTotalPaidLeave.Text = StaffDataTable[1].TotalLeave.ToString();
}
hth
Since you need to get TotalLeave from two rows, you need to fetch data from two rows.
if (StaffDataTable != null && StaffDataTable.Rows.Count > 1)
{
StaffAttendanceStatus.StaffTypesRow StaffRow1 = StaffDataTable[0];
StaffAttendanceStatus.StaffTypesRow StaffRow2 = StaffDataTable[1];
lblTotalMedicalLeave.Text = StaffRow1.TotalLeave.ToString();
lblTotalPaidLeave.Text = StaffRow2.TotalLeave.ToString();
}
if there is no order of PaidLeave and MedicalLave status, just check row.Status and assign total value to corresponding label

Changing ProdRouteJob has no effect to WrkCtrCapRes or recalculating the capacity reservations

I'm changing the route jobs (ProdRouteJob) with optimised data from an external optimisation tool. The changed data is written with a simple ax class and a prodRouteJob.update().
The problem now is, that the capacity reservations (WrkCtrCapRes) will not get updated. Is the a way to recalculate the capacity reservations? Or create new capacity reservations?
The only place where WrkCtrCapRes is updated is in the WrkCtrJobData.updateCapacityReservations() method. The class WrkCtrJobData requires WrkCtrScheduleJobs and other deep down complexities.
The ProdRouteJob does not have the full knowledge to update capacity reservation, it will have to take calendar into consideration.
I have made the following method to do a similar update. It does not support "Base calendar", but otherwise did what I needed.
Hours updateWrkCtrCapRes(ProdRouteJob prodRouteJob, WrkCtrTable wrkCtrTable = WrkCtrTable::find(prodRouteJob.WrkCtrId))
{
WrkCtrCapRes wrkCtrCapRes;
WorkCalendarDateLine workCalendarDateLine;
Seconds sec;
delete_from wrkCtrCapRes
where wrkCtrCapRes.RefType == WrkCtrCapRefType::Production &&
wrkCtrCapRes.RefId == prodRouteJob.ProdId &&
wrkCtrCapRes.OprNum == prodRouteJob.OprNum &&
wrkCtrCapRes.OprPriority == prodRouteJob.OprPriority &&
wrkCtrCapRes.JobId == prodRouteJob.JobId;
wrkCtrCapRes.ReqPlanId = ReqPlanSched::defaultDynamicId();
wrkCtrCapRes.LoadType = WrkCtrCapacityType::JobSched;
wrkCtrCapRes.RefType = WrkCtrCapRefType::Production;
wrkCtrCapRes.RefId = prodRouteJob.ProdId;
wrkCtrCapRes.OprNum = prodRouteJob.OprNum;
wrkCtrCapRes.OprPriority = prodRouteJob.OprPriority;
wrkCtrCapRes.JobType = prodRouteJob.JobType;
wrkCtrCapRes.JobId = prodRouteJob.JobId;
wrkCtrCapRes.Locked = prodRouteJob.Locked;
wrkCtrCapRes.WrkCtrGroupId = wrkCtrTable.WrkCtrGroupId;
wrkCtrCapRes.WrkCtrId = wrkCtrTable.WrkCtrId;
wrkCtrCapRes.WrkCtrLoadPct = 100.0;
while select workCalendarDateLine
where workCalendarDateLine.CalendarId == wrkCtrTable.CalendarId &&
workCalendarDateLine.TransDate >= prodRouteJob.FromDate &&
workCalendarDateLine.TransDate <= prodRouteJob.ToDate
{
if (workCalendarDateLine.TransDate == prodRouteJob.FromDate)
workCalendarDateLine.FromTime = max(workCalendarDateLine.FromTime, prodRouteJob.FromTime);
if (workCalendarDateLine.TransDate == prodRouteJob.ToDate)
workCalendarDateLine.ToTime = min(workCalendarDateLine.ToTime, prodRouteJob.ToTime);
if (workCalendarDateLine.FromTime < workCalendarDateLine.ToTime)
{
wrkCtrCapRes.TransDate = workCalendarDateLine.TransDate;
wrkCtrCapRes.StartTime = workCalendarDateLine.FromTime;
wrkCtrCapRes.EndTime = workCalendarDateLine.ToTime;
wrkCtrCapRes.WrkCtrSec = wrkCtrCapRes.EndTime - wrkCtrCapRes.StartTime;
wrkCtrCapRes.insert();
sec += wrkCtrCapRes.WrkCtrSec;
}
}
return decRound(sec / 3600.0, 5);
}
I simply added this method :
static void ProdSchedule(ProdId _ProdId)
{
ProdTableType ProdTableType;
ProdTable ProdTable=ProdTable::find(_ProdId);
ProdParmScheduling ProdParmScheduling;
;
ProdTableType=new ProdTableType(ProdTable);
ProdParmScheduling = ProdParmScheduling::findLast(_ProdId,ProdSchedMethod::JobScheduling); ProdTableType.runJobScheduling(ProdParmScheduling);
}

Resources