Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
JR Dalrymple
/
pf_interface_usage
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
d1f77b80
authored
Nov 22, 2015
by
JR Dalrymple
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Got the billing period logic all working it seems
Corrected path issue (better) for interfaces with '/'
parent
0a6b29b0
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
104 additions
and
38 deletions
+104
-38
check_snmp_usage.py
+104
-38
No files found.
check_snmp_usage.py
View file @
d1f77b80
...
...
@@ -11,17 +11,14 @@
# go CRITICAL when you've actually surpassed your allotment. Will use
# command line SNMP so no extra Python libraries are required.
#
# TODO: - Everything
# - As an added feature I'll someday make it work on daily caps and
# additionally make it so you can adjust the day of the month to reset
# - Add in the ability to use perfdata as a simple bandwidth
# method to create graphs in Nagios
# TODO:
# - SNMP v3?
# - Still don't have the logic for when the period rolls - I have about
# 29 days to figure this out :)
# - Make the usage/documentation better
#
#
# Release Hitory:
# Release History:
#
# 0.1 - basic functionality
#
#################################################################################
...
...
@@ -34,7 +31,9 @@ import subprocess
import
datetime
host
=
''
billingPeriodArg
=
'm1'
debug
=
0
rotate
=
False
communityString
=
'public'
OIDDateTime
=
'.1.3.6.1.2.1.25.1.2.0'
OIDIfDescr
=
'.1.3.6.1.2.1.2.2.1.2'
...
...
@@ -92,7 +91,7 @@ def getInterfaces():
def
usage
():
print
(
'Usage: check_snmp_usage.py -H hostname -i interface -b bandwidth limit (bytes) -c community string
\n
'
)
try
:
opts
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
'H:i:b:cdp'
)
opts
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
'H:i:b:cdp
:
'
)
except
getopt
.
GetoptError
as
err
:
print
(
err
)
usage
()
...
...
@@ -137,6 +136,8 @@ else:
multiplier
=
limitMatch
.
search
(
bytesLimit
)
.
group
(
2
)
if
multiplier
:
bytesLimit
=
int
(
scalar
)
*
int
(
unitMultipliers
[
multiplier
])
# validate billing period data
if
not
'billingPeriodArg'
in
locals
():
billingPeriod
=
0
...
...
@@ -157,8 +158,8 @@ else:
print
(
'When using monthly billing cycle it is necessary to specify a day between 1 and 31 inclusive.'
)
sys
.
exit
(
3
)
elif
billingPeriod
==
'd'
:
if
int
(
billTime
)
<
0
or
int
(
billTime
)
>
2
4
:
print
(
'When using daily billing cycle it is necessary to specify an hour between 0 and 2
4
inclusive.'
)
if
int
(
billTime
)
<
0
or
int
(
billTime
)
>
2
3
:
print
(
'When using daily billing cycle it is necessary to specify an hour between 0 and 2
3
inclusive.'
)
# Not optimized - we'll be getting all of the interfaces from the remote system and match up the indexes
...
...
@@ -210,10 +211,8 @@ current['outbytes'] = stdout.rstrip().split()[-1]
# Time to see if we have a temp file in place or not and read it if we do
tmpFile
=
'/tmp/check_snmp_usage_'
+
host
+
'_'
+
interface
+
'.tmp'
# If the interface name has forward slashes (Cisco) they need to be replaced
tmpFile
=
tmpFile
.
replace
(
'/'
,
'_'
)
interfacePath
=
interface
.
replace
(
'/'
,
'_'
)
tmpFile
=
'/tmp/check_snmp_usage_'
+
host
+
'_'
+
interfacePath
+
'.tmp'
if
os
.
path
.
isfile
(
tmpFile
):
...
...
@@ -249,6 +248,71 @@ currentDateStr = current['year'] + ' ' + current['month'] + ' ' + current['day']
lastDateTime
=
datetime
.
datetime
.
strptime
(
lastDateStr
,
format
)
currentDateTime
=
datetime
.
datetime
.
strptime
(
currentDateStr
,
format
)
# Before we go any farther - we will identify if we rotated from one period to the next
# and adjust the file as appropriate - then throw out this iteration of the check
# for all other purposes
# Identify the datetimes to test for:
interestingPeriodEnds
=
[]
# Daily periods:
if
billingPeriod
==
'd'
:
todayPeriodEndStr
=
current
[
'year'
]
+
' '
+
current
[
'month'
]
+
' '
+
current
[
'day'
]
+
' '
+
billTime
+
' 00 00'
thisPeriodEndDateTime
=
datetime
.
datetime
.
strptime
(
todayPeriodEndStr
,
format
)
yesterdayPeriodEndDateTime
=
thisPeriodEndDateTime
-
datetime
.
timedelta
(
days
=
1
)
interestingPeriodEnds
.
append
(
yesterdayPeriodEndDateTime
)
interestingPeriodEnds
.
append
(
thisPeriodEndDateTime
)
# Monthly periods:
# This is actually the number of days in the prior month - it's the right way
if
billingPeriod
==
'm'
:
monthDays
=
{
'1'
:
31
,
'2'
:
31
,
'3'
:
28
,
'4'
:
31
,
'5'
:
30
,
'6'
:
31
,
'7'
:
30
,
'8'
:
31
,
'9'
:
31
,
'10'
:
30
,
'11'
:
31
,
'12'
:
30
,
}
thisMonthPeriodEndStr
=
current
[
'year'
]
+
' '
+
current
[
'month'
]
+
' '
+
billTime
+
' 00 00 00'
thisPeriodEndDateTime
=
datetime
.
datetime
.
strptime
(
thisMonthPeriodEndStr
,
format
)
lastMonthPeriodEndDateTime
=
thisPeriodEndDateTime
-
datetime
.
timedelta
(
days
=
monthDays
[
current
[
'month'
]])
interestingPeriodEnds
.
append
(
lastMonthPeriodEndDateTime
)
interestingPeriodEnds
.
append
(
thisPeriodEndDateTime
)
for
date
in
interestingPeriodEnds
:
# This check iteration is crossing a billing period boundary
if
lastDateTime
<
date
and
currentDateTime
>
date
and
not
rotate
:
fileLines
.
append
(
fileLines
[
-
1
]
+
os
.
linesep
)
fileLines
[
-
2
]
=
'**ARCHIVE** '
+
fileLines
[
-
2
]
startOfBillingPeriod
=
date
if
billingPeriod
==
'm'
:
endOfBillingPeriod
=
thisPeriodEndDateTime
+
datetime
.
timedelta
(
days
=
monthDays
[
str
(
int
(
current
[
'month'
])
+
1
)])
if
billingPeriod
==
'd'
:
endOfBillingPeriod
=
thisPeriodEndDateTime
+
datetime
.
timedelta
(
days
=
1
)
rotate
=
True
elif
lastDateTime
>
date
:
startOfBillingPeriod
=
date
endOfBillingPeriod
=
thisPeriodEndDateTime
if
endOfBillingPeriod
<
currentDateTime
:
if
billingPeriod
==
'm'
:
endOfBillingPeriod
=
thisPeriodEndDateTime
+
datetime
.
timedelta
(
days
=
monthDays
[
str
(
int
(
current
[
'month'
])
+
1
)])
if
billingPeriod
==
'd'
:
endOfBillingPeriod
=
thisPeriodEndDateTime
+
datetime
.
timedelta
(
days
=
1
)
timeDifference
=
currentDateTime
-
lastDateTime
if
int
(
current
[
'inbytes'
])
>
int
(
last
[
'inbytes'
])
and
int
(
current
[
'outbytes'
])
>
int
(
last
[
'outbytes'
]):
...
...
@@ -261,7 +325,8 @@ if int(current['inbytes']) > int(last['inbytes']) and int(current['outbytes']) >
outLine
=
current
[
'year'
]
+
'|'
+
current
[
'month'
]
+
'|'
+
current
[
'day'
]
+
'|'
+
current
[
'hour'
]
+
'|'
+
current
[
'minute'
]
+
'|'
+
current
[
'second'
]
+
'|'
+
current
[
'inbytes'
]
+
'|'
+
current
[
'outbytes'
]
+
'|'
+
str
(
inBytesTotal
)
+
'|'
+
str
(
outBytesTotal
)
fileLines
[
-
1
]
=
outLine
f
=
open
(
tmpFile
,
'w'
)
f
.
write
(
outLine
)
for
line
in
fileLines
:
f
.
write
(
line
)
f
.
close
()
else
:
print
(
'Seems the counter went whacky, we need to reset things'
)
...
...
@@ -270,32 +335,26 @@ else:
outLine
=
current
[
'year'
]
+
'|'
+
current
[
'month'
]
+
'|'
+
current
[
'day'
]
+
'|'
+
current
[
'hour'
]
+
'|'
+
current
[
'minute'
]
+
'|'
+
current
[
'second'
]
+
'|'
+
current
[
'inbytes'
]
+
'|'
+
current
[
'outbytes'
]
+
'|'
+
last
[
'inbytestotal'
]
+
'|'
+
last
[
'outbytestotal'
]
fileLines
[
-
1
]
=
outLine
f
=
open
(
tmpFile
,
'w'
)
f
.
write
(
outLine
)
for
line
in
fileLines
:
f
.
write
(
line
)
f
.
close
()
sys
.
exit
(
3
)
# Files should be done, time to do Nagios logic
# Calculate number of seconds into month so far
beginningOfMonthStr
=
current
[
'year'
]
+
' '
+
current
[
'month'
]
+
' 1 00 00 00'
beginningOfMonthDateTime
=
datetime
.
datetime
.
strptime
(
beginningOfMonthStr
,
format
)
secondsIntoMonth
=
currentDateTime
-
beginningOfMonthDateTime
#
Calculate number of seconds in the current month
if
current
[
'month'
]
==
'12'
:
nextMonth
=
'1'
nextYear
=
int
(
current
[
'year'
])
+
1
else
:
nextMonth
=
int
(
current
[
'month'
])
+
1
nextYear
=
current
[
'year'
]
#
billingPeriod = m or d
# billTime = 0-31 or 0-23
# startOfBillingPeriod = datetime object
# endOfBillingPeriod = datetime object
periodLength
=
endOfBillingPeriod
-
startOfBillingPeriod
secondsIntoPeriod
=
currentDateTime
-
startOfBillingPeriod
beginningOfNextMonthStr
=
str
(
nextYear
)
+
' '
+
str
(
nextMonth
)
+
' 1 00 00 00'
beginningOfNextMonthDateTime
=
datetime
.
datetime
.
strptime
(
beginningOfNextMonthStr
,
format
)
secondsInMonth
=
beginningOfNextMonthDateTime
-
beginningOfMonthDateTime
# Percentage of
month
complete
monthComplete
=
(
float
(
secondsIntoMonth
.
total_seconds
())
/
float
(
secondsInMon
th
.
total_seconds
())
)
*
100
# Percentage of
period
complete
periodComplete
=
(
float
(
secondsIntoPeriod
.
total_seconds
())
/
float
(
periodLeng
th
.
total_seconds
())
)
*
100
# Percentage of data used
...
...
@@ -313,22 +372,29 @@ perfdata = '|\'BytesInRate\'=' + str(inBytesPerSec) +'bytes/sec;;;;\'BytesOutRat
if
totalDataUsed
>
bytesLimit
:
print
(
'CRITICAL - You have exceeded your alloted data usage for this period'
+
perfdata
)
print
(
'You are alloted '
+
str
(
bytesLimit
)
+
' bytes for the month but have already used '
+
str
(
totalDataUsed
)
+
' bytes.'
)
print
(
'You are alloted '
+
str
(
bytesLimit
)
+
' bytes for the period but have already used '
+
str
(
totalDataUsed
)
+
' bytes.'
)
print
(
'The current billing period started on '
+
str
(
startOfBillingPeriod
))
print
(
'The current billing period ends on '
+
str
(
endOfBillingPeriod
))
sys
.
exit
(
2
)
elif
percentageDataUsed
>
month
Complete
:
elif
percentageDataUsed
>
period
Complete
:
print
(
'WARNING - You are using data at a rate that will cause you to exceed usage allotment for this period'
+
perfdata
)
print
(
'The
month is '
+
str
(
round
(
month
Complete
,
2
))
+
'
%
complete.'
)
print
(
'The
period is '
+
str
(
round
(
period
Complete
,
2
))
+
'
%
complete.'
)
print
(
'The data allotment on interface '
+
interface
+
' is '
+
str
(
round
(
percentageDataUsed
,
2
))
+
'
%
used.'
)
print
(
'The current billing period started on '
+
str
(
startOfBillingPeriod
))
print
(
'The current billing period ends on '
+
str
(
endOfBillingPeriod
))
sys
.
exit
(
1
)
else
:
print
(
'OK - You will not use all of your alloted data for this period at the current rate'
+
perfdata
)
print
(
'The
month is '
+
str
(
round
(
month
Complete
,
2
))
+
'
%
complete.'
)
print
(
'The
period is '
+
str
(
round
(
period
Complete
,
2
))
+
'
%
complete.'
)
print
(
'The data allotment on interface '
+
interface
+
' is '
+
str
(
round
(
percentageDataUsed
,
2
))
+
'
%
used.'
)
print
(
'The current billing period started on '
+
str
(
startOfBillingPeriod
))
print
(
'The current billing period ends on '
+
str
(
endOfBillingPeriod
))
sys
.
exit
(
0
)
if
debug
==
1
:
print
(
'The
month is '
+
str
(
round
(
month
Complete
,
2
))
+
'
%
complete.'
)
print
(
'The
period is '
+
str
(
round
(
period
Complete
,
2
))
+
'
%
complete.'
)
print
(
'The data allotment on interface '
+
interface
+
' is '
+
str
(
round
(
percentageDataUsed
,
2
))
+
'
%
used.'
)
print
(
'The current incoming rate is '
+
str
(
inBytesPerSec
)
+
' bytes/second.'
)
print
(
'The current outgoing rate is '
+
str
(
outBytesPerSec
)
+
' bytes/second.'
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment