Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
fd51c3e5
Commit
fd51c3e5
authored
Jan 24, 2006
by
Jim Fulton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simple script to analyze trace logs.
parent
610d49be
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
223 additions
and
0 deletions
+223
-0
utilities/tracelog.py
utilities/tracelog.py
+223
-0
No files found.
utilities/tracelog.py
0 → 100644
View file @
fd51c3e5
##############################################################################
#
# Copyright (c) 2006 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Yet another trace log analysis tool
$Id$
"""
import
datetime
,
optparse
,
sys
class
Request
:
output_bytes
=
'-'
def
__init__
(
self
,
start
,
method
,
url
):
self
.
method
=
method
self
.
url
=
url
self
.
start
=
start
self
.
state
=
'input'
def
I
(
self
,
input_time
,
input_bytes
):
self
.
input_time
=
input_time
self
.
input_bytes
=
input_bytes
self
.
state
=
'app'
def
A
(
self
,
app_time
,
response
,
output_bytes
):
self
.
app_time
=
app_time
self
.
response
=
response
self
.
output_bytes
=
output_bytes
self
.
state
=
'output'
def
E
(
self
,
end
):
self
.
end
=
end
@
property
def
app_seconds
(
self
):
return
(
self
.
app_time
-
self
.
input_time
).
seconds
@
property
def
total_seconds
(
self
):
return
(
self
.
end
-
self
.
start
).
seconds
def
parsedt
(
s
):
date
,
time
=
s
.
split
(
'T'
)
return
datetime
.
datetime
(
*
(
map
(
int
,
date
.
split
(
'-'
))
+
map
(
int
,
time
.
split
(
':'
))
))
def
main
(
args
=
None
):
if
args
is
None
:
args
=
sys
.
argv
[
1
:]
options
,
args
=
parser
.
parse_args
(
args
)
if
options
.
event_log
:
restarts
=
find_restarts
(
options
.
event_log
)
else
:
restarts
=
[]
restarts
.
append
(
datetime
.
datetime
.
utcnow
()
+
datetime
.
timedelta
(
1000
))
[
file
]
=
args
lmin
=
ldt
=
None
requests
=
{}
input
=
apps
=
output
=
n
=
0
spr
=
spa
=
0.0
restart
=
restarts
.
pop
(
0
)
for
record
in
open
(
file
):
record
=
record
.
split
()
typ
,
rid
,
dt
=
record
[:
3
]
min
=
dt
[:
-
3
]
dt
=
parsedt
(
dt
)
if
dt
==
restart
:
continue
while
dt
>
restart
:
print_app_requests
(
requests
,
ldt
,
options
.
old_requests
,
options
.
app_requests
,
"
\
n
Left over:"
)
requests
=
{}
input
=
apps
=
output
=
n
=
0
spr
=
spa
=
0.0
restart
=
restarts
.
pop
(
0
)
ldt
=
dt
if
min
!=
lmin
:
if
lmin
is
not
None
:
print
lmin
.
replace
(
'T'
,
' '
),
"%4d I=%3d A=%3d O=%3d "
%
(
len
(
requests
),
input
,
apps
,
output
),
if
n
:
print
"N=%4d %10.2f %10.2f"
%
(
n
,
spr
/
n
,
spa
/
n
)
else
:
print
if
apps
>
options
.
apps
:
print_app_requests
(
requests
,
dt
,
options
.
old_requests
,
options
.
app_requests
,
)
lmin
=
min
spr
=
0.0
spa
=
0.0
n
=
0
if
typ
==
'B'
:
input
+=
1
requests
[
rid
]
=
Request
(
dt
,
*
record
[
3
:
5
])
elif
typ
==
'I'
:
if
rid
in
requests
:
input
-=
1
apps
+=
1
requests
[
rid
].
I
(
dt
,
record
[
3
])
elif
typ
==
'A'
:
if
rid
in
requests
:
apps
-=
1
output
+=
1
requests
[
rid
].
A
(
dt
,
*
record
[
3
:
5
])
elif
typ
==
'E'
:
if
rid
in
requests
:
output
-=
1
request
=
requests
.
pop
(
rid
)
request
.
E
(
dt
)
spr
+=
request
.
total_seconds
spa
+=
request
.
app_seconds
n
+=
1
else
:
print
'WTF'
,
record
print_app_requests
(
requests
,
dt
,
options
.
old_requests
,
options
.
app_requests
,
"Left over:"
)
def
find_restarts
(
event_log
):
result
=
[]
for
l
in
open
(
event_log
):
if
l
.
strip
().
endswith
(
"Zope Ready to handle requests"
):
result
.
append
(
parsedt
(
l
.
split
()[
0
]))
return
result
def
print_app_requests
(
requests
,
dt
,
min_seconds
,
max_requests
,
label
=
''
):
requests
=
[
((
dt
-
request
.
input_time
).
seconds
,
request
)
for
request
in
requests
.
values
()
if
request
.
state
==
'app'
]
requests
.
sort
()
requests
.
reverse
()
for
s
,
request
in
requests
[:
max_requests
]:
if
s
<
min_seconds
:
continue
if
label
:
print
label
label
=
''
print
s
,
request
.
url
parser
=
optparse
.
OptionParser
(
"""
Usage: %prog [options] trace_log_file
Output trace log data showing:
- number of active requests,
- number of input requests (requests gathering input),
- number of application requests,
- number of output requests,
- number of requests completed in the minute shown,
- mean seconds per request and
- mean application seconds per request.
Note that we don't seem to be logging when a connection to the client
is broken, so the number of active requests, and especially the number
of outputing requests tends to grow over time. This is spurious.
Also, note that, unfortunately, application requests include requests
that are running in application threads and requests waiting to get an
application thread.
When application threads get above the app request threshold, then we
show the requests that have been waiting the longest.
"""
)
parser
.
add_option
(
"--app-request-threshold"
,
"-a"
,
dest
=
'apps'
,
type
=
"int"
,
default
=
10
,
help
=
"""
Number of pending application requests at which detailed request information
if printed.
"""
)
parser
.
add_option
(
"--app-requests"
,
"-r"
,
dest
=
'app_requests'
,
type
=
"int"
,
default
=
10
,
help
=
"""
How many requests to show when the maximum number of pending
apps is exceeded.
"""
)
parser
.
add_option
(
"--old-requests"
,
"-o"
,
dest
=
'old_requests'
,
type
=
"int"
,
default
=
10
,
help
=
"""
Number of seconds beyond which a request is considered old.
"""
)
parser
.
add_option
(
"--event-log"
,
"-e"
,
dest
=
'event_log'
,
help
=
"""
The name of an event log that goes with the trace log. This is used
to determine when the server is restarted, so that the running trace data structures can be reinitialized.
"""
)
if
__name__
==
'__main__'
:
main
()
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