I am trying to generate alert when the Cisco router's interface throughput exceeds certain value. Please have a look at my code.
I am using telegraph to collect the data. My measurement "monitor usage" contains multiple field keys and values. How to separate them and alert on each of them? Am I using "derivative" node correctly? Is it the field key I should use in the "derivative" node?
Is there a way to log each node output to help troubleshooting? In my case, how do I see "bytes_recv_per_sec" value as being calculated by the "alert" node?
What does "log" node do exactly? Where is the log file? I don't see much valuable information in "/var/log/kapacitor/kapacitor.log"
I have tried playing with different nodes with different parameter methods without much success. Thanks for any help.
dbrp "telegraf"."autogen"
stream
|from()
.measurement('monitor usage')
.where(lambda: "agent_host" == '10.92.192.15')
|window()
.period(1m)
.every(1m)
|httpOut('dump')
|stats(1m)
|httpOut('stats')
|derivative('Envision_Po1.891_ifHCInOctets')
.unit(1s).nonNegative()
.as('bytes_recv_per_sec')
|alert()
.warn(lambda: "bytes_recv_per_sec" > 40.0)
.crit(lambda: "bytes_recv_per_sec" > 80.0)
// post to logfile
.log('/tmp/alerts.log')
At this stage I want to see "/tmp/alerts.log" to generate some alert message when the alert threshold is met. Eventually I want to send an alert email.
As per request, here is info about my database on the "monitor usage" measurement
> show series from "monitor usage";
key
---
monitor\ usage,agent_host=10.85.1.5,host=dzhao-trex,sw_name=it-na-wan-pro-01-11p.int.pason.com
monitor\ usage,agent_host=10.85.1.6,host=dzhao-trex,sw_name=it-na-wan-pro-02-11p.int.pason.com
monitor\ usage,agent_host=10.92.192.15,host=dzhao-trex,rtr_name=irt01-00rm255r2r1.int.pason.com
monitor\ usage,agent_host=10.92.192.17,host=dzhao-trex,sw_name=wsw01-00rm255r2r1.pason.com
monitor\ usage,agent_host=172.19.254.200,host=dzhao-trex,sw_name=ssw01-04rm120r7.int.pason.com
monitor\ usage,agent_host=192.168.195.1,host=dzhao-trex,sw_name=wrt01-06.int.pason.com
> show field keys from "monitor usage";
name: monitor usage
fieldKey fieldType
-------- ---------
Envision_Po1.891_ifHCInOctets integer
Envision_Po1.891_ifHCOutOctets integer
Gi0/0/0_ifHCInOctets integer
Gi0/0/0_ifHCOutOctets integer
GigabitEthernet0/0/0_ifHCInOctets integer
GigabitEthernet0/0/0_ifHCOutOctets integer
GigabitEthernet0/0/2_ifHCInOctets integer
GigabitEthernet0/0/2_ifHCOutOctets integer
HE_Po1.892_ifHCInOctets integer
HE_Po1.892_ifHCOutOctets integer
Po1003_ifHCInOctets integer
Po1003_ifHCOutOctets integer
Rogers_Po1.894_ifHCInOctets integer
Rogers_Po1.894_ifHCOutOctets integer
Shaw_Po1.893_ifHCInOctets integer
Shaw_Po1.893_ifHCOutOctets integer
Te2/5/6_ifHCInOctets integer
Te2/5/6_ifHCOutOctets integer
Tunnel100_ifHCInOctets integer
Tunnel100_ifHCOutOctets integer
Tunnel1_ifHCInOctets integer
Tunnel1_ifHCOutOctets integer
Tunnel2_ifHCInOctets integer
Tunnel2_ifHCOutOctets integer
YYCIX_Gi0/0/1_ifHCInOctets integer
YYCIX_Gi0/0/1_ifHCOutOctets integer
> show tag keys from "monitor usage";
name: monitor usage
tagKey
------
agent_host
host
rtr_name
sw_name
Related
A string '321#322#323#324#325'.
here number of digits in each number is 3 but it's not limited to 3 it could be any number.
here are 5 numbers in a string but this number could be anything.
task is to get 321,322,323,324,325 and store in a table so that any operation could be performed over them.
I have tried several string functions like c = c:gsub('%W','') to eliminate those non-alphanumeric characters, but nothing helped.
function encrypter()--FUNCTION 14
c=' '
print('Please enter your message!')
local message=io.read()
lengthOfString=string.len(message)--Inbuit function to get length of a string.
newLine()
print('Please enter your key. Remember this key, otherwise your message wont be decrypted')
newLine()
key=io.read()
key=tonumber(key)
largeSpace()
print("Encrypted message is")
for s=1,lengthOfString do
--print(encryptionFormula(string.byte(message,s),key))
--inbuilt function for converting character of a string to it's respective ASCII value. First place gets character or variable having string whereas second place gets position of that character in the given string.
b=encryptionFormula(string.byte(message,s),key)
c=c..tostring(b)..'#'
--print(c)
b=0
end
print(c)
largeSpace()
print("Now share this message along with the key to the receiver. Don't share your key with anyone, if you don't want your message to be read.")
end
What you're looking for is string.gmatch().
local input = "123#546514#13#548#2315"
local numbers = {}
for number in string.gmatch(input, '%d+') do
table.insert(numbers, number)
end
-- Output the numbers
for index, number in ipairs(numbers) do
print(index, number)
-- This prints:
-- 1 123
-- 2 546514
-- 3 13
-- 4 548
-- 5 2315
end
If you don't know how Lua patterns work, you can read about them in the reference manual or you can have a look at Programming in Lua (the first edition is available for free on their website)
I've got a DOORS module with attributes that are filled with number strings, because the attributes are not applicable to all objects. To identify unambiuously the objects which aren't affected, the attributes currently contain "N/A" . For purposes of sorting and other operations, I would like to replace these attributes with numeric types. Is there any special value that DOORS understands as "NULL" or "N/A", or even 'Inf' that can be used in a numeric attribute?
I know I could do some scripting to create separate DXL attributes which convert the number strings to numeric but would rather avoid that if possible.
I fear that you will either have to stick to strings or define your personal integer value which represents 'n/a', for example '0'. Objects with the '0' value will be easy to treat after sorting -- with DXL you may use the bool null(t value) function which checks if value is null (bool: false, char: '0', int: 0, real: 0.0, string: ""). If you stick to integer strings, there is the function bool isValidInt(string s) which would help you to treat the "n/a" string accordingly.
Could you just leave the attribute empty for that object?
It seems like an int type attribute can be set to "" - and you could filter the objects based on that attribute being empty or non-empty.
Interestingly, in DXL space, the following seems to work for an integer based attribute ( inttest )
Object o = current
int x = o."inttest"
print ( x ) "\n"
print ( null x ) "\n"
print ( x == 0 )
Prints the following results:
0
true
true
So nulls are interpreted into 0 - something to be aware of if 0 is an expected value in your attributes.
I have a variable that looks like this " 88.0*" or " 79.5 " where the asterisk is a flag for something. To extract this flag I run
gen newvar = regexm(oldvar,"\*$")
This works fine, but my new variable is a float, which seems inefficient.
Stata offers storage in byte format, so why doesn't the regexm command (which indicates 0/1 whether a match was found) default to that? For that matter, why doesn't generate (abbreviated gen above) compress the right-hand side by default, or at least as an option?
You can specify the storage type after the gen:
clear
set more off
input ///
str5(var1 var2)
"88.0*" "79.5 "
end
list
gen byte newvar = regexm(var1,"\*$")
list
describe
Note that Stata has no boolean type. A 0 is false, a 1 is true. The syntax for generate is (from help generate):
generate [type] newvar[:lblname] =exp [if] [in]
The type appears between brackets, which means it is an option.
See also help compress to reduce memory used by the data.
I have created a mapping of copybook elements to WSDL fields. And the map was built successfully. But while running the map locally, I am getting either of the two error for the two different operations that I am mapping:
1) For the first mapping: 'Input valid but unknown data found' and in the trace logs I am getting : INPUT 1 exists (3012 bytes) but has no content.
More details of error:
(Level 0: Offset 0, len 0, comp 1 of 0, #1, DI 000000000001:)
Data at offset 0 ('<retrFunction1'
of TYPE X'0004' (retrFunction1Request retrFunction1Request Message WSDLService).
INPUT 1 exists (3012 bytes) but has no content.
End of Validation messages for INPUT CARD 1.
(Offset 26130: Map Number 0 (CobolFuncData), DI 000000000000:)
TYPE X'0148' (COBOL_OBJECT Group CopyBook) has been built.
(Offset 26130: Map Number 0 (CobolFuncData), DI 000000000000:)
TYPE X'0124' (000_COBOL_OPERATION Record CopyBook) has been built.
OUTPUT 1 was built successfully.
2) For the second mapping: 'One of more inputs are invalid' and in the trace logs I am getting : INPUT 1 exists, but its type is in error.
Further for case2 I am getting:
(Level 3: Offset 0, len 0, comp 1 of 2, #1, DI 000000000001:)
Data at offset 0 ('xmlns'
of TYPE X'0008' (Prefix XMLS WSDLService).
I think the issue is not with the mapping of WSDL type trees with the COBOL type trees but with the XML Request and Response data that I am using for running these maps locally. Is there any guidelines that I can use to create the correct input and run the map locally successfully in WTX.
PS. I am using creating the type tree by importing WSDL and not XSD. I am not getting the node 'DOC' in the type tree when I imported my WSDL. In this case what type tree level should I be using for creating my map. I have tried WSDLService -> Type -> ~TypeName -> TypeDef and WSDLService -> Type -> ~TypeName -> Seq
I found one reason for this issue myself. The reason being that the request XML did not match the type tree level I was using in the mapping for the transformation. The better way to do this mapping if you are using a WSDL instead of XSD (and 'DOC XSD' doesn't show up in your WSDL/XSD type tree) is to use type for your input card as the 'input' for your operation from the WSDL (as n example: Input yourOperationName Operation yourWSDLService).
As a rule, it is most important to fully understand your WSDL and WSDL operation and XSD strutures in order to create mappings for your transformations.
I have many text files of this format
....
<snip>
'FOP' 0.19 1 24 1 25 7 8 /
'FOP' 0.18 1 24 1 25 9 11 /
/
TURX
560231
300244
70029
200250
645257
800191
900333
600334
770291
300335
220287
110262 /
SUBTRACT
'TURX' 'TURY'/
</snip>
......
where the portions I snipped off contain other various data in various formats. The file format is inconsistent (machine generated), the only thing one is assured of is the keyword TURX which may appear more than once. If it appears alone on one line, then the next few lines will contain numbers that I need to fetch into an array. The last number will have a space then a forward slash (/). I can then use this array in other operations afterwards.
How do I "search" or parse a file of unknown format in fortran, and how do I get a loop to fetch the rest of the data, please? I am really new to this and I HAVE to use fortran. Thanks.
Fortran 95 / 2003 have a lot of string and file handling features that make this easier.
For example, this code fragment to process a file of unknown length:
use iso_fortran_env
character (len=100) :: line
integer :: ReadCode
ReadLoop: do
read (75, '(A)', iostat=ReadCode ) line
if ( ReadCode /= 0 ) then
if ( ReadCode == iostat_end ) then
exit ReadLoop
else
write ( *, '( / "Error reading file: ", I0 )' ) ReadCode
stop
end if
end if
! code to process the line ....
end do ReadLoop
Then the "process the line" code can contain several sections depending on a logical variable "Have_TURX". If Have_TRUX is false you are "seeking" ... test whether the line contains "TURX". You could use a plain "==" if TURX is always at the start of the string, or for more generality you could use the intrinsic function "index" to test whether the string "line" contains TURX.
Once the program is in the mode Have_TRUX is true, then you use "internal I/O" to read the numeric value from the string. Since the integers have varying lengths and are left-justified, the easiest way is to use "list-directed I/O": combining these:
read (line, *) integer_variable
Then you could use the intrinsic function "index" again to test whether the string also contains a slash, in which case you change Have_TRUX to false and end reading mode.
If you need to put the numbers into an array, it might be necessary to read the file twice, or to backspace the file, because you will have to allocate the array, and you can't do that until you know the size of the array. Or you could pop the numbers into a linked list, then when you hit the slash allocate the array and fill it from the linked list. Or if there is a known maximum number of values you could use a temporary array, then transfer the numbers to an allocatable output array. This is assuming that you want the output argument of the subroutine be an allocatable array of the correct length, and the it returns one group of numbers per call:
integer, dimension (:), allocatable, intent (out) :: numbers
allocate (numbers (1: HowMany) )
P.S. There is a brief summary of the language features at http://en.wikipedia.org/wiki/Fortran_95_language_features and the gfortran manual has a summary of the intrinsic procedures, from which you can see what built in functions are available for string handling.
I'll give you a nudge in the right direction so that you can finish your project.
Some basics:
Do/While as you'll need some sort of loop
structure to loop through the file
and then over the numbers. There's
no for loop in Fortran, so use this
type.
Read
to read the strings.
To start you need something like this:
program readlines
implicit none
character (len=30) :: rdline
integer,dimension(1000) :: array
! This sets up a character array with 30 positions and an integer array with 1000
!
open(18,file='fileread.txt')
do
read(18,*) rdline
if (trim(rdline).eq.'TURX') exit !loop until the trimmed off portion matches TURX
end do
See this thread for way to turn your strings into integers.
Final edit: Looks like MSB has got most of what I just found out. The iostat argument of the read is the key to it. See this site for a sample program.
Here was my final way around it.
PROGRAM fetchnumbers
implicit none
character (len=50) ::line, numdata
logical ::is_numeric
integer ::I,iost,iost2,counter=0,number
integer, parameter :: long = selected_int_kind(10)
integer, dimension(1000)::numbers !Can the number of numbers be up to 1000?
open(20,file='inputfile.txt') !assuming file is in the same location as program
ReadLoop: do
read(20,*,iostat=iost) line !read data line by line
if (iost .LT. 0) exit !end of file reached before TURX was found
if (len_trim(line)==0) cycle ReadLoop !ignore empty lines
if (index(line, 'TURX').EQ.1) then !prepare to begin capturing
GetNumbers: do
read(20, *,iostat=iost2)numdata !read in the numbers one by one
if (.NOT.is_numeric(numdata)) exit !no more numbers to read
if (iost2 .LT. 0) exit !end of file reached while fetching numbers
read (numdata,*) number !read string value into a number
counter = counter + 1
Storeloop: do I =1,counter
if (I<counter) cycle StoreLoop
numbers(counter)=number !storing data into array
end do StoreLoop
end do GetNumbers
end if
end do ReadLoop
write(*,*) "Numbers are:"
do I=1,counter
write(*,'(I14)') numbers(I)
end do
END PROGRAM fetchnumbers
FUNCTION is_numeric(string)
IMPLICIT NONE
CHARACTER(len=*), INTENT(IN) :: string
LOGICAL :: is_numeric
REAL :: x
INTEGER :: e
is_numeric = .FALSE.
READ(string,*,IOSTAT=e) x
IF (e == 0) is_numeric = .TRUE.
END FUNCTION is_numeric