Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
apachedex
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
Vincent Pelletier
apachedex
Commits
ffdc722a
Commit
ffdc722a
authored
Dec 19, 2023
by
Jérome Perrin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update for python3 >= 3.9
drop support for python 2
parent
943a005d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
122 additions
and
144 deletions
+122
-144
apachedex/__init__.py
apachedex/__init__.py
+89
-120
apachedex/tests.py
apachedex/tests.py
+32
-21
setup.py
setup.py
+1
-3
No files found.
apachedex/__init__.py
View file @
ffdc722a
...
@@ -26,23 +26,23 @@
...
@@ -26,23 +26,23 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
##############################################################################
##############################################################################
from
__future__
import
print_function
,
division
,
absolute_import
,
\
unicode_literals
from
html
import
escape
from
cgi
import
escape
from
collections
import
defaultdict
,
Counter
from
collections
import
defaultdict
,
Counter
from
datetime
import
datetime
,
timedelta
,
date
,
tzinfo
from
datetime
import
datetime
,
timedelta
,
date
,
tzinfo
from
functools
import
partial
from
functools
import
partial
from
operator
import
itemgetter
from
operator
import
itemgetter
from
urllib
import
splittype
,
splithost
from
urllib
.parse
import
splittype
,
splithost
import
argparse
import
argparse
import
bz2
import
bz2
import
calendar
import
calendar
import
codecs
import
codecs
import
functools
import
functools
import
gzip
import
gzip
import
http
lib
import
http
.client
import
itertools
import
itertools
import
json
import
json
import
lzma
import
math
import
math
import
os
import
os
import
pkgutil
import
pkgutil
...
@@ -61,47 +61,16 @@ except ImportError:
...
@@ -61,47 +61,16 @@ except ImportError:
def
getResource
(
name
,
encoding
=
'utf-8'
):
def
getResource
(
name
,
encoding
=
'utf-8'
):
return
pkgutil
.
get_data
(
__name__
,
name
).
decode
(
encoding
)
return
pkgutil
.
get_data
(
__name__
,
name
).
decode
(
encoding
)
def
_wrapOpen
(
func
):
@
functools
.
wraps
(
func
)
def
wrapper
(
*
args
,
**
kw
):
encoding
=
kw
.
pop
(
'encoding'
,
None
)
info
=
codecs
.
lookup
(
encoding
)
errors
=
kw
.
pop
(
'errors'
,
'strict'
)
file_object
=
func
(
*
args
,
**
kw
)
if
encoding
is
None
:
return
file_object
srw
=
codecs
.
StreamReaderWriter
(
file_object
,
info
.
streamreader
,
info
.
streamwriter
,
errors
,
)
srw
.
encoding
=
encoding
return
srw
return
wrapper
gzip_open
=
gzip
.
open
gzip_open
=
gzip
.
open
if
sys
.
version_info
>=
(
3
,
3
):
lzma_open
=
lzma
.
open
import
lzma
bz2_open
=
bz2
.
open
lzma_open
=
lzma
.
open
bz2_open
=
bz2
.
open
_read_mode
=
'rt'
else
:
gzip_open
=
_wrapOpen
(
gzip_open
)
bz2_open
=
_wrapOpen
(
bz2
.
BZ2File
)
_read_mode
=
'r'
try
:
from
backports
import
lzma
lzma_open
=
_wrapOpen
(
lzma
.
open
)
except
ImportError
:
lzma
=
None
FILE_OPENER_LIST
=
[
FILE_OPENER_LIST
=
[
(
gzip_open
,
IOError
),
(
gzip_open
,
IOError
),
(
bz2_open
,
IOError
),
(
bz2_open
,
IOError
),
(
lzma_open
,
lzma
.
LZMAError
)
]
]
if
lzma
is
not
None
:
FILE_OPENER_LIST
.
append
((
lzma_open
,
lzma
.
LZMAError
))
# XXX: what encoding ? apache doesn't document one, but requests are supposed
# XXX: what encoding ? apache doesn't document one, but requests are supposed
# to be urlencoded, so pure ascii. Are timestamps localised ?
# to be urlencoded, so pure ascii. Are timestamps localised ?
...
@@ -131,7 +100,7 @@ AUTO_PERIOD_COEF = 200
...
@@ -131,7 +100,7 @@ AUTO_PERIOD_COEF = 200
LARGER_THAN_INTEGER_STR
=
'A'
LARGER_THAN_INTEGER_STR
=
'A'
SMALLER_THAN_INTEGER_STR
=
''
SMALLER_THAN_INTEGER_STR
=
''
HTTP_STATUS_CAPTION_DICT
=
http
lib
.
responses
.
copy
()
HTTP_STATUS_CAPTION_DICT
=
http
.
client
.
responses
.
copy
()
# Non-standard status codes
# Non-standard status codes
HTTP_STATUS_CAPTION_DICT
.
setdefault
(
499
,
'Client Closed Request'
)
HTTP_STATUS_CAPTION_DICT
.
setdefault
(
499
,
'Client Closed Request'
)
HTTP_STATUS_CAPTION_DICT
.
setdefault
(
444
,
'No Response'
)
HTTP_STATUS_CAPTION_DICT
.
setdefault
(
444
,
'No Response'
)
...
@@ -153,9 +122,9 @@ def getClassForStatusHit(hit, status):
...
@@ -153,9 +122,9 @@ def getClassForStatusHit(hit, status):
def
getDataPoints
(
apdex_dict
,
status_period_dict
=
{}):
def
getDataPoints
(
apdex_dict
,
status_period_dict
=
{}):
period_error_dict
=
defaultdict
(
int
)
period_error_dict
=
defaultdict
(
int
)
for
status
,
period_dict
in
status_period_dict
.
ite
rite
ms
():
for
status
,
period_dict
in
status_period_dict
.
items
():
if
statusIsError
(
status
):
if
statusIsError
(
status
):
for
period
,
hit
in
period_dict
.
ite
rite
ms
():
for
period
,
hit
in
period_dict
.
items
():
period_error_dict
[
period
]
+=
hit
period_error_dict
[
period
]
+=
hit
# If there was an error, there was a hit, and apdex_dict must contain it
# If there was an error, there was a hit, and apdex_dict must contain it
# (at same date).
# (at same date).
...
@@ -166,7 +135,7 @@ def getDataPoints(apdex_dict, status_period_dict={}):
...
@@ -166,7 +135,7 @@ def getDataPoints(apdex_dict, status_period_dict={}):
apdex
.
getApdex
()
*
100
,
apdex
.
getApdex
()
*
100
,
apdex
.
hit
,
apdex
.
hit
,
period_error_dict
.
get
(
value_date
,
0
),
period_error_dict
.
get
(
value_date
,
0
),
)
for
value_date
,
apdex
in
sorted
(
apdex_dict
.
ite
rite
ms
(),
key
=
ITEMGETTER0
)
)
for
value_date
,
apdex
in
sorted
(
apdex_dict
.
items
(),
key
=
ITEMGETTER0
)
]
]
def
prepareDataForGraph
(
daily_data
,
date_format
,
placeholder_delta
,
def
prepareDataForGraph
(
daily_data
,
date_format
,
placeholder_delta
,
...
@@ -202,7 +171,7 @@ def graphPair(daily_data, date_format, graph_period, apdex_y_min=None,
...
@@ -202,7 +171,7 @@ def graphPair(daily_data, date_format, graph_period, apdex_y_min=None,
yLabelWidth
=
max
(
int
(
math
.
log10
(
max
(
x
[
2
]
for
x
in
daily_data
)))
+
1
,
yLabelWidth
=
max
(
int
(
math
.
log10
(
max
(
x
[
2
]
for
x
in
daily_data
)))
+
1
,
3
)
*
6
3
)
*
6
return
graph
(
'apdex'
,
return
graph
(
'apdex'
,
[
zip
(
date_list
,
(
round
(
x
[
1
],
2
)
for
x
in
daily_data
))],
[
list
(
zip
(
date_list
,
(
round
(
x
[
1
],
2
)
for
x
in
daily_data
)
))],
{
{
'xaxis'
:
{
'xaxis'
:
{
'mode'
:
'time'
,
'mode'
:
'time'
,
...
@@ -225,12 +194,12 @@ def graphPair(daily_data, date_format, graph_period, apdex_y_min=None,
...
@@ -225,12 +194,12 @@ def graphPair(daily_data, date_format, graph_period, apdex_y_min=None,
[
[
{
{
'label'
:
'Errors'
,
'label'
:
'Errors'
,
'data'
:
zip
(
date_list
,
(
x
[
3
]
for
x
in
daily_data
)),
'data'
:
list
(
zip
(
date_list
,
(
x
[
3
]
for
x
in
daily_data
)
)),
'color'
:
'red'
,
'color'
:
'red'
,
},
},
{
{
'label'
:
'Hits'
,
'label'
:
'Hits'
,
'data'
:
zip
(
date_list
,
(
x
[
2
]
for
x
in
daily_data
)),
'data'
:
list
(
zip
(
date_list
,
(
x
[
2
]
for
x
in
daily_data
)
)),
},
},
],
],
{
{
...
@@ -326,7 +295,7 @@ class APDEXStats(object):
...
@@ -326,7 +295,7 @@ class APDEXStats(object):
extra_class
=
''
extra_class
=
''
apdex_style
=
'color: #%s; background-color: #%s'
%
(
apdex_style
=
'color: #%s; background-color: #%s'
%
(
(
apdex
<
.
5
and
'f'
or
'0'
)
*
3
,
(
apdex
<
.
5
and
'f'
or
'0'
)
*
3
,
(
'%x'
%
(
apdex
*
0xf
))
*
3
,
(
'%x'
%
int
(
apdex
*
0xf
))
*
3
,
)
)
else
:
else
:
extra_class
=
'no_hit'
extra_class
=
'no_hit'
...
@@ -363,7 +332,7 @@ class APDEXStats(object):
...
@@ -363,7 +332,7 @@ class APDEXStats(object):
return
result
return
result
_APDEXDateDictAsJSONState
=
lambda
date_dict
:
dict
(((
y
,
z
.
asJSONState
())
_APDEXDateDictAsJSONState
=
lambda
date_dict
:
dict
(((
y
,
z
.
asJSONState
())
for
y
,
z
in
date_dict
.
ite
rite
ms
()))
for
y
,
z
in
date_dict
.
items
()))
class
GenericSiteStats
(
object
):
class
GenericSiteStats
(
object
):
def
__init__
(
self
,
threshold
,
getDuration
,
suffix
,
error_detail
=
False
,
def
__init__
(
self
,
threshold
,
getDuration
,
suffix
,
error_detail
=
False
,
...
@@ -383,13 +352,13 @@ class GenericSiteStats(object):
...
@@ -383,13 +352,13 @@ class GenericSiteStats(object):
self
.
user_agent_counter
=
Counter
()
self
.
user_agent_counter
=
Counter
()
def
rescale
(
self
,
convert
,
getDuration
):
def
rescale
(
self
,
convert
,
getDuration
):
for
status
,
date_dict
in
self
.
status
.
ite
rite
ms
():
for
status
,
date_dict
in
self
.
status
.
items
():
new_date_dict
=
defaultdict
(
int
)
new_date_dict
=
defaultdict
(
int
)
for
value_date
,
status_count
in
date_dict
.
ite
rite
ms
():
for
value_date
,
status_count
in
date_dict
.
items
():
new_date_dict
[
convert
(
value_date
)]
+=
status_count
new_date_dict
[
convert
(
value_date
)]
+=
status_count
self
.
status
[
status
]
=
new_date_dict
self
.
status
[
status
]
=
new_date_dict
new_apdex
=
defaultdict
(
partial
(
APDEXStats
,
self
.
threshold
,
getDuration
))
new_apdex
=
defaultdict
(
partial
(
APDEXStats
,
self
.
threshold
,
getDuration
))
for
value_date
,
data
in
self
.
apdex
.
ite
rite
ms
():
for
value_date
,
data
in
self
.
apdex
.
items
():
new_apdex
[
convert
(
value_date
)].
accumulateFrom
(
data
)
new_apdex
[
convert
(
value_date
)].
accumulateFrom
(
data
)
self
.
apdex
=
new_apdex
self
.
apdex
=
new_apdex
...
@@ -422,7 +391,7 @@ class GenericSiteStats(object):
...
@@ -422,7 +391,7 @@ class GenericSiteStats(object):
result
=
[]
result
=
[]
append
=
result
.
append
append
=
result
.
append
apdex
=
APDEXStats
(
self
.
threshold
,
None
)
apdex
=
APDEXStats
(
self
.
threshold
,
None
)
for
data
in
self
.
apdex
.
iter
values
():
for
data
in
self
.
apdex
.
values
():
apdex
.
accumulateFrom
(
data
)
apdex
.
accumulateFrom
(
data
)
append
(
'<h2>Overall</h2><table class="stats"><tr>'
)
append
(
'<h2>Overall</h2><table class="stats"><tr>'
)
append
(
APDEXStats
.
asHTMLHeader
())
append
(
APDEXStats
.
asHTMLHeader
())
...
@@ -431,7 +400,7 @@ class GenericSiteStats(object):
...
@@ -431,7 +400,7 @@ class GenericSiteStats(object):
append
(
'</tr></table><h2>Hottest pages</h2><table class="stats"><tr>'
)
append
(
'</tr></table><h2>Hottest pages</h2><table class="stats"><tr>'
)
append
(
APDEXStats
.
asHTMLHeader
())
append
(
APDEXStats
.
asHTMLHeader
())
append
(
'<th>url</th></tr>'
)
append
(
'<th>url</th></tr>'
)
for
url
,
data
in
sorted
(
self
.
url_apdex
.
ite
rite
ms
(),
key
=
lambda
x
:
x
[
1
].
getAverage
()
*
x
[
1
].
hit
,
for
url
,
data
in
sorted
(
self
.
url_apdex
.
items
(),
key
=
lambda
x
:
x
[
1
].
getAverage
()
*
x
[
1
].
hit
,
reverse
=
True
)[:
n_hottest_pages
]:
reverse
=
True
)[:
n_hottest_pages
]:
append
(
'<tr>'
)
append
(
'<tr>'
)
append
(
data
.
asHTML
(
self
.
threshold
))
append
(
data
.
asHTML
(
self
.
threshold
))
...
@@ -445,9 +414,9 @@ class GenericSiteStats(object):
...
@@ -445,9 +414,9 @@ class GenericSiteStats(object):
append
(
'</table>'
)
append
(
'</table>'
)
column_set
=
set
()
column_set
=
set
()
filtered_status
=
defaultdict
(
partial
(
defaultdict
,
int
))
filtered_status
=
defaultdict
(
partial
(
defaultdict
,
int
))
for
status
,
date_dict
in
self
.
status
.
ite
rite
ms
():
for
status
,
date_dict
in
self
.
status
.
items
():
filtered_date_dict
=
filtered_status
[
status
]
filtered_date_dict
=
filtered_status
[
status
]
for
value_date
,
value
in
date_dict
.
ite
rite
ms
():
for
value_date
,
value
in
date_dict
.
items
():
filtered_date_dict
[
stat_filter
(
value_date
)]
+=
value
filtered_date_dict
[
stat_filter
(
value_date
)]
+=
value
column_set
.
update
(
filtered_date_dict
)
column_set
.
update
(
filtered_date_dict
)
column_list
=
sorted
(
column_set
)
column_list
=
sorted
(
column_set
)
...
@@ -466,25 +435,24 @@ class GenericSiteStats(object):
...
@@ -466,25 +435,24 @@ class GenericSiteStats(object):
else
:
else
:
return
'<abbr title="%s">%s</abbr>'
%
(
definition
,
status
)
return
'<abbr title="%s">%s</abbr>'
%
(
definition
,
status
)
has_errors
=
False
has_errors
=
False
for
status
,
data_dict
in
sorted
(
filtered_status
.
iteritems
(),
for
status
,
data_dict
in
sorted
(
filtered_status
.
items
(),
key
=
ITEMGETTER0
):
key
=
ITEMGETTER0
):
has_errors
|=
statusIsError
(
status
)
has_errors
|=
statusIsError
(
status
)
append
(
'<tr title="%s"><th>%s</th>'
%
(
status
,
statusAsHtml
(
status
)))
append
(
'<tr title="%s"><th>%s</th>'
%
(
status
,
statusAsHtml
(
status
)))
append
(
hitTd
(
sum
(
data_dict
.
iter
values
()),
status
))
append
(
hitTd
(
sum
(
data_dict
.
values
()),
status
))
for
column
in
column_list
:
for
column
in
column_list
:
append
(
hitTd
(
data_dict
[
column
],
status
))
append
(
hitTd
(
data_dict
[
column
],
status
))
append
(
'</tr>'
)
append
(
'</tr>'
)
append
(
'</table>'
)
append
(
'</table>'
)
if
self
.
error_detail
and
has_errors
:
if
self
.
error_detail
and
has_errors
:
def
getHitForUrl
(
referer_counter
):
def
getHitForUrl
(
referer_counter
):
return
sum
(
referer_counter
.
iter
values
())
return
sum
(
referer_counter
.
values
())
filtered_status_url
=
defaultdict
(
partial
(
defaultdict
,
dict
))
filtered_status_url
=
defaultdict
(
partial
(
defaultdict
,
dict
))
for
status
,
url_dict
in
self
.
error_url_count
.
ite
rite
ms
():
for
status
,
url_dict
in
self
.
error_url_count
.
items
():
filtered_status_url
[
status
]
=
sorted
(
url_dict
.
ite
rite
ms
(),
filtered_status_url
[
status
]
=
sorted
(
url_dict
.
items
(),
key
=
lambda
x
:
getHitForUrl
(
x
[
1
]),
reverse
=
True
)[:
N_ERROR_URL
]
key
=
lambda
x
:
getHitForUrl
(
x
[
1
]),
reverse
=
True
)[:
N_ERROR_URL
]
append
(
'<h3>Error detail</h3><table class="stats"><tr><th>status</th>'
append
(
'<h3>Error detail</h3><table class="stats"><tr><th>status</th>'
'<th>hits</th><th>url</th><th>referers</th></tr>'
)
'<th>hits</th><th>url</th><th>referers</th></tr>'
)
for
status
,
url_list
in
sorted
(
filtered_status_url
.
ite
rite
ms
(),
for
status
,
url_list
in
sorted
(
filtered_status_url
.
items
(),
key
=
ITEMGETTER0
):
key
=
ITEMGETTER0
):
append
(
'<tr><th rowspan="%s">%s</th>'
%
(
len
(
url_list
),
append
(
'<tr><th rowspan="%s">%s</th>'
%
(
len
(
url_list
),
statusAsHtml
(
status
)))
statusAsHtml
(
status
)))
...
@@ -513,16 +481,16 @@ class GenericSiteStats(object):
...
@@ -513,16 +481,16 @@ class GenericSiteStats(object):
state
.
get
(
'user_agent_detail'
,
True
))
state
.
get
(
'user_agent_detail'
,
True
))
if
error_detail
:
if
error_detail
:
error_url_count
=
result
.
error_url_count
error_url_count
=
result
.
error_url_count
for
state_status
,
state_url_dict
in
state
[
'error_url_count'
].
ite
rite
ms
():
for
state_status
,
state_url_dict
in
state
[
'error_url_count'
].
items
():
url_dict
=
error_url_count
[
state_status
]
url_dict
=
error_url_count
[
state_status
]
for
url
,
counter
in
state_url_dict
.
ite
rite
ms
():
for
url
,
counter
in
state_url_dict
.
items
():
url_dict
[
url
].
update
(
counter
)
url_dict
[
url
].
update
(
counter
)
for
attribute_id
in
(
'url_apdex'
,
'apdex'
):
for
attribute_id
in
(
'url_apdex'
,
'apdex'
):
attribute
=
getattr
(
result
,
attribute_id
)
attribute
=
getattr
(
result
,
attribute_id
)
for
key
,
apdex_state
in
state
[
attribute_id
].
ite
rite
ms
():
for
key
,
apdex_state
in
state
[
attribute_id
].
items
():
attribute
[
key
]
=
APDEXStats
.
fromJSONState
(
apdex_state
,
getDuration
)
attribute
[
key
]
=
APDEXStats
.
fromJSONState
(
apdex_state
,
getDuration
)
status
=
result
.
status
status
=
result
.
status
for
status_code
,
date_dict
in
state
[
'status'
].
ite
rite
ms
():
for
status_code
,
date_dict
in
state
[
'status'
].
items
():
status
[
status_code
].
update
(
date_dict
)
status
[
status_code
].
update
(
date_dict
)
result
.
user_agent_counter
.
update
(
state
[
'user_agent_counter'
])
result
.
user_agent_counter
.
update
(
state
[
'user_agent_counter'
])
return
result
return
result
...
@@ -544,18 +512,18 @@ class GenericSiteStats(object):
...
@@ -544,18 +512,18 @@ class GenericSiteStats(object):
# user_agent_detail.
# user_agent_detail.
# Assuming they are consistently set.
# Assuming they are consistently set.
if
self
.
error_detail
:
if
self
.
error_detail
:
for
status
,
other_url_dict
in
other
.
error_url_count
.
ite
rite
ms
():
for
status
,
other_url_dict
in
other
.
error_url_count
.
items
():
url_dict
=
self
.
error_url_count
[
status
]
url_dict
=
self
.
error_url_count
[
status
]
for
url
,
referer_counter
in
other_url_dict
.
ite
rite
ms
():
for
url
,
referer_counter
in
other_url_dict
.
items
():
url_dict
[
url
].
update
(
referer_counter
)
url_dict
[
url
].
update
(
referer_counter
)
for
attribute_id
in
(
'url_apdex'
,
'apdex'
):
for
attribute_id
in
(
'url_apdex'
,
'apdex'
):
self_attribute
=
getattr
(
self
,
attribute_id
)
self_attribute
=
getattr
(
self
,
attribute_id
)
for
key
,
apdex_data
in
getattr
(
other
,
attribute_id
).
ite
rite
ms
():
for
key
,
apdex_data
in
getattr
(
other
,
attribute_id
).
items
():
self_attribute
[
key
].
accumulateFrom
(
apdex_data
)
self_attribute
[
key
].
accumulateFrom
(
apdex_data
)
status
=
self
.
status
status
=
self
.
status
for
status_code
,
other_date_dict
in
other
.
status
.
ite
rite
ms
():
for
status_code
,
other_date_dict
in
other
.
status
.
items
():
date_dict
=
status
[
status_code
]
date_dict
=
status
[
status_code
]
for
status_date
,
count
in
other_date_dict
.
ite
rite
ms
():
for
status_date
,
count
in
other_date_dict
.
items
():
date_dict
[
status_date
]
+=
count
date_dict
[
status_date
]
+=
count
self
.
user_agent_counter
.
update
(
other
.
user_agent_counter
)
self
.
user_agent_counter
.
update
(
other
.
user_agent_counter
)
...
@@ -594,21 +562,21 @@ class ERP5SiteStats(GenericSiteStats):
...
@@ -594,21 +562,21 @@ class ERP5SiteStats(GenericSiteStats):
def
rescale
(
self
,
convert
,
getDuration
):
def
rescale
(
self
,
convert
,
getDuration
):
super
(
ERP5SiteStats
,
self
).
rescale
(
convert
,
getDuration
)
super
(
ERP5SiteStats
,
self
).
rescale
(
convert
,
getDuration
)
threshold
=
self
.
threshold
threshold
=
self
.
threshold
for
document_dict
in
self
.
module
.
iter
values
():
for
document_dict
in
self
.
module
.
values
():
for
is_document
,
date_dict
in
document_dict
.
ite
rite
ms
():
for
is_document
,
date_dict
in
document_dict
.
items
():
new_date_dict
=
defaultdict
(
partial
(
APDEXStats
,
threshold
,
getDuration
))
new_date_dict
=
defaultdict
(
partial
(
APDEXStats
,
threshold
,
getDuration
))
for
value_date
,
data
in
date_dict
.
ite
rite
ms
():
for
value_date
,
data
in
date_dict
.
items
():
new_date_dict
[
convert
(
value_date
)].
accumulateFrom
(
data
)
new_date_dict
[
convert
(
value_date
)].
accumulateFrom
(
data
)
document_dict
[
is_document
]
=
new_date_dict
document_dict
[
is_document
]
=
new_date_dict
for
id_
,
date_dict
in
self
.
no_module
.
ite
rite
ms
():
for
id_
,
date_dict
in
self
.
no_module
.
items
():
new_date_dict
=
defaultdict
(
partial
(
APDEXStats
,
threshold
,
getDuration
))
new_date_dict
=
defaultdict
(
partial
(
APDEXStats
,
threshold
,
getDuration
))
for
value_date
,
data
in
date_dict
.
ite
rite
ms
():
for
value_date
,
data
in
date_dict
.
items
():
new_date_dict
[
convert
(
value_date
)].
accumulateFrom
(
data
)
new_date_dict
[
convert
(
value_date
)].
accumulateFrom
(
data
)
self
.
no_module
[
id_
]
=
new_date_dict
self
.
no_module
[
id_
]
=
new_date_dict
attribute
=
defaultdict
(
partial
(
APDEXStats
,
threshold
,
getDuration
))
attribute
=
defaultdict
(
partial
(
APDEXStats
,
threshold
,
getDuration
))
for
value_date
,
data
in
self
.
site_search
.
ite
rite
ms
():
for
value_date
,
data
in
self
.
site_search
.
items
():
attribute
[
convert
(
value_date
)].
accumulateFrom
(
data
)
attribute
[
convert
(
value_date
)].
accumulateFrom
(
data
)
self
.
site_search
=
attribute
self
.
site_search
=
attribute
...
@@ -647,23 +615,23 @@ class ERP5SiteStats(GenericSiteStats):
...
@@ -647,23 +615,23 @@ class ERP5SiteStats(GenericSiteStats):
filtered_no_module
=
defaultdict
(
partial
(
filtered_no_module
=
defaultdict
(
partial
(
defaultdict
,
partial
(
APDEXStats
,
self
.
threshold
,
None
)))
defaultdict
,
partial
(
APDEXStats
,
self
.
threshold
,
None
)))
column_set
=
set
()
column_set
=
set
()
for
key
,
data_dict
in
self
.
no_module
.
ite
rite
ms
():
for
key
,
data_dict
in
self
.
no_module
.
items
():
filtered_id_dict
=
filtered_no_module
[
key
]
filtered_id_dict
=
filtered_no_module
[
key
]
for
value_date
,
value
in
data_dict
.
ite
rite
ms
():
for
value_date
,
value
in
data_dict
.
items
():
filtered_id_dict
[
stat_filter
(
value_date
)].
accumulateFrom
(
value
)
filtered_id_dict
[
stat_filter
(
value_date
)].
accumulateFrom
(
value
)
other_overall
.
accumulateFrom
(
value
)
other_overall
.
accumulateFrom
(
value
)
column_set
.
update
(
filtered_id_dict
)
column_set
.
update
(
filtered_id_dict
)
filtered_site_search
=
defaultdict
(
partial
(
APDEXStats
,
self
.
threshold
,
filtered_site_search
=
defaultdict
(
partial
(
APDEXStats
,
self
.
threshold
,
None
))
None
))
for
value_date
,
value
in
self
.
site_search
.
ite
rite
ms
():
for
value_date
,
value
in
self
.
site_search
.
items
():
filtered_site_search
[
stat_filter
(
value_date
)].
accumulateFrom
(
value
)
filtered_site_search
[
stat_filter
(
value_date
)].
accumulateFrom
(
value
)
column_set
.
update
(
filtered_site_search
)
column_set
.
update
(
filtered_site_search
)
for
key
,
is_document_dict
in
self
.
module
.
ite
rite
ms
():
for
key
,
is_document_dict
in
self
.
module
.
items
():
filtered_is_document_dict
=
filtered_module
[
key
]
filtered_is_document_dict
=
filtered_module
[
key
]
for
key
,
data_dict
in
is_document_dict
.
ite
rite
ms
():
for
key
,
data_dict
in
is_document_dict
.
items
():
filtered_data_dict
=
filtered_is_document_dict
[
key
]
filtered_data_dict
=
filtered_is_document_dict
[
key
]
module_document_apdex
=
module_document_overall
[
key
]
module_document_apdex
=
module_document_overall
[
key
]
for
value_date
,
value
in
data_dict
.
ite
rite
ms
():
for
value_date
,
value
in
data_dict
.
items
():
filtered_data_dict
[
stat_filter
(
value_date
)].
accumulateFrom
(
value
)
filtered_data_dict
[
stat_filter
(
value_date
)].
accumulateFrom
(
value
)
module_document_apdex
.
accumulateFrom
(
value
)
module_document_apdex
.
accumulateFrom
(
value
)
column_set
.
update
(
filtered_data_dict
)
column_set
.
update
(
filtered_data_dict
)
...
@@ -671,12 +639,12 @@ class ERP5SiteStats(GenericSiteStats):
...
@@ -671,12 +639,12 @@ class ERP5SiteStats(GenericSiteStats):
for
column
in
column_list
:
for
column
in
column_list
:
append
(
'<th colspan="4">%s</th>'
%
column
)
append
(
'<th colspan="4">%s</th>'
%
column
)
append
(
'</tr><tr>'
)
append
(
'</tr><tr>'
)
for
i
in
x
range
(
len
(
column_list
)
+
1
):
for
i
in
range
(
len
(
column_list
)
+
1
):
append
(
APDEXStats
.
asHTMLHeader
(
i
==
0
))
append
(
APDEXStats
.
asHTMLHeader
(
i
==
0
))
append
(
'</tr>'
)
append
(
'</tr>'
)
def
apdexAsColumns
(
data_dict
):
def
apdexAsColumns
(
data_dict
):
data_total
=
APDEXStats
(
self
.
threshold
,
None
)
data_total
=
APDEXStats
(
self
.
threshold
,
None
)
for
data
in
data_dict
.
iter
values
():
for
data
in
data_dict
.
values
():
data_total
.
accumulateFrom
(
data
)
data_total
.
accumulateFrom
(
data
)
append
(
data_total
.
asHTML
(
self
.
threshold
,
True
))
append
(
data_total
.
asHTML
(
self
.
threshold
,
True
))
for
column
in
column_list
:
for
column
in
column_list
:
...
@@ -711,8 +679,7 @@ class ERP5SiteStats(GenericSiteStats):
...
@@ -711,8 +679,7 @@ class ERP5SiteStats(GenericSiteStats):
))
))
append
(
'</div></div>'
)
append
(
'</div></div>'
)
append
(
'</td>'
)
append
(
'</td>'
)
for
module_id
,
data_dict
in
sorted
(
filtered_module
.
iteritems
(),
for
module_id
,
data_dict
in
sorted
(
filtered_module
.
items
(),
key
=
ITEMGETTER0
):
key
=
ITEMGETTER0
):
append
(
'<tr class="group_top" title="%s (module)"><th rowspan="2">%s</th>'
append
(
'<tr class="group_top" title="%s (module)"><th rowspan="2">%s</th>'
'<th>module</th>'
%
(
module_id
,
module_id
))
'<th>module</th>'
%
(
module_id
,
module_id
))
hiddenGraph
(
self
.
module
[
module_id
][
False
],
module_id
+
' (module)'
)
hiddenGraph
(
self
.
module
[
module_id
][
False
],
module_id
+
' (module)'
)
...
@@ -726,7 +693,7 @@ class ERP5SiteStats(GenericSiteStats):
...
@@ -726,7 +693,7 @@ class ERP5SiteStats(GenericSiteStats):
hiddenGraph
(
self
.
site_search
,
'site search'
)
hiddenGraph
(
self
.
site_search
,
'site search'
)
site_search_overall
=
apdexAsColumns
(
filtered_site_search
)
site_search_overall
=
apdexAsColumns
(
filtered_site_search
)
append
(
'</tr>'
)
append
(
'</tr>'
)
for
id_
,
date_dict
in
sorted
(
filtered_no_module
.
ite
rite
ms
()):
for
id_
,
date_dict
in
sorted
(
filtered_no_module
.
items
()):
append
(
'<tr class="group_top group_bottom" title="%s"><th colspan="2">%s</th>'
append
(
'<tr class="group_top group_bottom" title="%s"><th colspan="2">%s</th>'
%
(
id_
,
id_
))
%
(
id_
,
id_
))
hiddenGraph
(
self
.
no_module
[
id_
],
id_
)
hiddenGraph
(
self
.
no_module
[
id_
],
id_
)
...
@@ -758,20 +725,20 @@ class ERP5SiteStats(GenericSiteStats):
...
@@ -758,20 +725,20 @@ class ERP5SiteStats(GenericSiteStats):
@
classmethod
@
classmethod
def
fromJSONState
(
cls
,
state
,
getDuration
,
suffix
):
def
fromJSONState
(
cls
,
state
,
getDuration
,
suffix
):
result
=
super
(
ERP5SiteStats
,
cls
).
fromJSONState
(
state
,
getDuration
,
suffix
)
result
=
super
(
ERP5SiteStats
,
cls
).
fromJSONState
(
state
,
getDuration
,
suffix
)
for
module_id
,
module_dict_state
in
state
[
'module'
].
ite
rite
ms
():
for
module_id
,
module_dict_state
in
state
[
'module'
].
items
():
module_dict
=
result
.
module
[
module_id
]
module_dict
=
result
.
module
[
module_id
]
for
is_document
,
date_dict_state
in
module_dict_state
.
ite
rite
ms
():
for
is_document
,
date_dict_state
in
module_dict_state
.
items
():
date_dict
=
module_dict
[
is_document
==
'true'
]
date_dict
=
module_dict
[
is_document
==
'true'
]
for
value_date
,
apdex_state
in
date_dict_state
.
ite
rite
ms
():
for
value_date
,
apdex_state
in
date_dict_state
.
items
():
date_dict
[
value_date
]
=
APDEXStats
.
fromJSONState
(
apdex_state
,
getDuration
)
date_dict
[
value_date
]
=
APDEXStats
.
fromJSONState
(
apdex_state
,
getDuration
)
for
id_
,
date_dict
in
state
[
'no_module'
].
ite
rite
ms
():
for
id_
,
date_dict
in
state
[
'no_module'
].
items
():
no_module_dict
=
result
.
no_module
[
id_
]
no_module_dict
=
result
.
no_module
[
id_
]
for
value_date
,
apdex_state
in
date_dict
.
ite
rite
ms
():
for
value_date
,
apdex_state
in
date_dict
.
items
():
no_module_dict
[
value_date
]
=
APDEXStats
.
fromJSONState
(
no_module_dict
[
value_date
]
=
APDEXStats
.
fromJSONState
(
apdex_state
,
getDuration
)
apdex_state
,
getDuration
)
for
value_date
,
apdex_state
in
state
[
'site_search'
].
ite
rite
ms
():
for
value_date
,
apdex_state
in
state
[
'site_search'
].
items
():
result
.
site_search
[
value_date
]
=
APDEXStats
.
fromJSONState
(
result
.
site_search
[
value_date
]
=
APDEXStats
.
fromJSONState
(
apdex_state
,
getDuration
)
apdex_state
,
getDuration
)
...
@@ -780,13 +747,13 @@ class ERP5SiteStats(GenericSiteStats):
...
@@ -780,13 +747,13 @@ class ERP5SiteStats(GenericSiteStats):
def
asJSONState
(
self
):
def
asJSONState
(
self
):
result
=
super
(
ERP5SiteStats
,
self
).
asJSONState
()
result
=
super
(
ERP5SiteStats
,
self
).
asJSONState
()
result
[
'module'
]
=
module
=
{}
result
[
'module'
]
=
module
=
{}
for
module_id
,
module_dict
in
self
.
module
.
ite
rite
ms
():
for
module_id
,
module_dict
in
self
.
module
.
items
():
module_dict_state
=
module
[
module_id
]
=
{}
module_dict_state
=
module
[
module_id
]
=
{}
for
is_document
,
date_dict
in
module_dict
.
ite
rite
ms
():
for
is_document
,
date_dict
in
module_dict
.
items
():
module_dict_state
[
is_document
]
=
_APDEXDateDictAsJSONState
(
date_dict
)
module_dict_state
[
is_document
]
=
_APDEXDateDictAsJSONState
(
date_dict
)
result
[
'no_module'
]
=
no_module
=
{}
result
[
'no_module'
]
=
no_module
=
{}
for
id_
,
date_dict
in
self
.
no_module
.
ite
rite
ms
():
for
id_
,
date_dict
in
self
.
no_module
.
items
():
no_module
[
id_
]
=
_APDEXDateDictAsJSONState
(
date_dict
)
no_module
[
id_
]
=
_APDEXDateDictAsJSONState
(
date_dict
)
result
[
'site_search'
]
=
_APDEXDateDictAsJSONState
(
self
.
site_search
)
result
[
'site_search'
]
=
_APDEXDateDictAsJSONState
(
self
.
site_search
)
...
@@ -795,20 +762,20 @@ class ERP5SiteStats(GenericSiteStats):
...
@@ -795,20 +762,20 @@ class ERP5SiteStats(GenericSiteStats):
def
accumulateFrom
(
self
,
other
):
def
accumulateFrom
(
self
,
other
):
super
(
ERP5SiteStats
,
self
).
accumulateFrom
(
other
)
super
(
ERP5SiteStats
,
self
).
accumulateFrom
(
other
)
module
=
self
.
module
module
=
self
.
module
for
module_id
,
other_module_dict
in
other
.
module
.
ite
rite
ms
():
for
module_id
,
other_module_dict
in
other
.
module
.
items
():
module_dict
=
module
[
module_id
]
module_dict
=
module
[
module_id
]
for
is_document
,
other_date_dict
in
other_module_dict
.
ite
rite
ms
():
for
is_document
,
other_date_dict
in
other_module_dict
.
items
():
date_dict
=
module_dict
[
is_document
]
date_dict
=
module_dict
[
is_document
]
for
value_date
,
apdex
in
other_date_dict
.
ite
rite
ms
():
for
value_date
,
apdex
in
other_date_dict
.
items
():
date_dict
[
value_date
].
accumulateFrom
(
apdex
)
date_dict
[
value_date
].
accumulateFrom
(
apdex
)
for
id_
,
other_date_dict
in
other
.
no_module
.
ite
rite
ms
():
for
id_
,
other_date_dict
in
other
.
no_module
.
items
():
date_dict
=
self
.
no_module
[
id_
]
date_dict
=
self
.
no_module
[
id_
]
for
value_date
,
apdex
in
other_date_dict
.
ite
rite
ms
():
for
value_date
,
apdex
in
other_date_dict
.
items
():
date_dict
.
accumulateFrom
(
apdex
)
date_dict
.
accumulateFrom
(
apdex
)
attribute
=
self
.
site_search
attribute
=
self
.
site_search
for
value_date
,
apdex
in
other
.
site_search
.
ite
rite
ms
():
for
value_date
,
apdex
in
other
.
site_search
.
items
():
attribute
[
value_date
].
accumulateFrom
(
apdex
)
attribute
[
value_date
].
accumulateFrom
(
apdex
)
DURATION_US_FORMAT
=
'%D'
DURATION_US_FORMAT
=
'%D'
...
@@ -861,7 +828,7 @@ class AggregateSiteUrl(argparse.Action):
...
@@ -861,7 +828,7 @@ class AggregateSiteUrl(argparse.Action):
def
__call__
(
self
,
parser
,
namespace
,
values
,
option_string
=
None
):
def
__call__
(
self
,
parser
,
namespace
,
values
,
option_string
=
None
):
action
=
base_action
=
self
.
__argument_to_aggregator
[
option_string
]
action
=
base_action
=
self
.
__argument_to_aggregator
[
option_string
]
site_list
,
site_caption_dict
=
getattr
(
namespace
,
self
.
dest
)
site_list
,
site_caption_dict
=
getattr
(
namespace
,
self
.
dest
)
next_value
=
iter
(
values
).
next
next_value
=
iter
(
values
).
__next__
while
True
:
while
True
:
try
:
try
:
value
=
next_value
()
value
=
next_value
()
...
@@ -917,7 +884,7 @@ class ShlexArgumentParser(argparse.ArgumentParser):
...
@@ -917,7 +884,7 @@ class ShlexArgumentParser(argparse.ArgumentParser):
shlex
.
split
(
in_file
.
read
(),
comments
=
True
),
shlex
.
split
(
in_file
.
read
(),
comments
=
True
),
new_cwd
,
new_cwd
,
))
))
except
IOError
,
exc
:
except
IOError
as
exc
:
self
.
error
(
str
(
exc
))
self
.
error
(
str
(
exc
))
else
:
else
:
append
(
arg
)
append
(
arg
)
...
@@ -1125,7 +1092,7 @@ def asHTML(out, encoding, per_site, args, default_site, period_parameter_dict,
...
@@ -1125,7 +1092,7 @@ def asHTML(out, encoding, per_site, args, default_site, period_parameter_dict,
apdex_y_scale
=
apdex_y_scale_dict
[
args
.
apdex_yscale
]
apdex_y_scale
=
apdex_y_scale_dict
[
args
.
apdex_yscale
]
hit_y_scale
=
hit_y_scale_dict
[
args
.
hit_yscale
]
hit_y_scale
=
hit_y_scale_dict
[
args
.
hit_yscale
]
out
.
write
(
'</head><body><h1>Overall</h1>'
)
out
.
write
(
'</head><body><h1>Overall</h1>'
)
site_list
=
list
(
enumerate
(
sorted
(
per_site
.
ite
rite
ms
(),
site_list
=
list
(
enumerate
(
sorted
(
per_site
.
items
(),
key
=
lambda
x
:
site_caption_dict
[
x
[
0
]])))
key
=
lambda
x
:
site_caption_dict
[
x
[
0
]])))
html_site_caption_dict
=
{}
html_site_caption_dict
=
{}
for
i
,
(
site_id
,
_
)
in
site_list
:
for
i
,
(
site_id
,
_
)
in
site_list
:
...
@@ -1149,7 +1116,7 @@ def asHTML(out, encoding, per_site, args, default_site, period_parameter_dict,
...
@@ -1149,7 +1116,7 @@ def asHTML(out, encoding, per_site, args, default_site, period_parameter_dict,
hit_per_day
=
defaultdict
(
int
)
hit_per_day
=
defaultdict
(
int
)
x_min
=
LARGER_THAN_INTEGER_STR
x_min
=
LARGER_THAN_INTEGER_STR
x_max
=
SMALLER_THAN_INTEGER_STR
x_max
=
SMALLER_THAN_INTEGER_STR
for
site_data
in
per_site
.
iter
values
():
for
site_data
in
per_site
.
values
():
apdex_data_list
=
site_data
.
getApdexData
()
apdex_data_list
=
site_data
.
getApdexData
()
if
apdex_data_list
:
if
apdex_data_list
:
x_min
=
min
(
x_min
,
apdex_data_list
[
0
][
0
])
x_min
=
min
(
x_min
,
apdex_data_list
[
0
][
0
])
...
@@ -1159,7 +1126,7 @@ def asHTML(out, encoding, per_site, args, default_site, period_parameter_dict,
...
@@ -1159,7 +1126,7 @@ def asHTML(out, encoding, per_site, args, default_site, period_parameter_dict,
if
x_min
==
LARGER_THAN_INTEGER_STR
:
if
x_min
==
LARGER_THAN_INTEGER_STR
:
x_min
=
None
x_min
=
None
x_max
=
None
x_max
=
None
for
hit_date
,
hit
in
sorted
(
hit_per_day
.
ite
rite
ms
(),
key
=
ITEMGETTER0
):
for
hit_date
,
hit
in
sorted
(
hit_per_day
.
items
(),
key
=
ITEMGETTER0
):
out
.
write
(
'<tr><td>%s</td><td>%s</td></tr>'
%
(
hit_date
,
hit
))
out
.
write
(
'<tr><td>%s</td><td>%s</td></tr>'
%
(
hit_date
,
hit
))
out
.
write
(
'</table>'
)
out
.
write
(
'</table>'
)
n_hottest_pages
=
args
.
n_hottest_pages
n_hottest_pages
=
args
.
n_hottest_pages
...
@@ -1230,7 +1197,7 @@ def asHTML(out, encoding, per_site, args, default_site, period_parameter_dict,
...
@@ -1230,7 +1197,7 @@ def asHTML(out, encoding, per_site, args, default_site, period_parameter_dict,
out
.
write
(
'</body></html>'
)
out
.
write
(
'</body></html>'
)
def
asJSON
(
out
,
encoding
,
per_site
,
*
_
):
def
asJSON
(
out
,
encoding
,
per_site
,
*
_
):
json
.
dump
([(
x
,
y
.
asJSONState
())
for
x
,
y
in
per_site
.
ite
rite
ms
()],
out
)
json
.
dump
([(
x
,
y
.
asJSONState
())
for
x
,
y
in
per_site
.
items
()],
out
)
format_generator
=
{
format_generator
=
{
'html'
:
(
asHTML
,
'utf-8'
),
'html'
:
(
asHTML
,
'utf-8'
),
...
@@ -1365,7 +1332,7 @@ def main():
...
@@ -1365,7 +1332,7 @@ def main():
group
.
add_argument
(
'--erp5-base'
,
dest
=
'path'
,
nargs
=
'+'
,
group
.
add_argument
(
'--erp5-base'
,
dest
=
'path'
,
nargs
=
'+'
,
action
=
AggregateSiteUrl
,
action
=
AggregateSiteUrl
,
help
=
'Similar to --base, but with specialised statistics. Ex: '
help
=
'Similar to --base, but with specialised statistics. Ex: '
'"/erp5(/|$|
\
?)
"
'
)
'"/erp5(/|$|
\
\
?)"'
)
group
.
add_argument
(
'--skip-base'
,
dest
=
'path'
,
nargs
=
'+'
,
group
.
add_argument
(
'--skip-base'
,
dest
=
'path'
,
nargs
=
'+'
,
action
=
AggregateSiteUrl
,
action
=
AggregateSiteUrl
,
help
=
'Absolute base url(s) to ignore.'
)
help
=
'Absolute base url(s) to ignore.'
)
...
@@ -1409,7 +1376,7 @@ def main():
...
@@ -1409,7 +1376,7 @@ def main():
line_regex
=
''
line_regex
=
''
expensive_line_regex
=
''
expensive_line_regex
=
''
try
:
try
:
n
=
iter
(
args
.
logformat
).
next
n
=
iter
(
args
.
logformat
).
__next__
while
True
:
while
True
:
key
=
None
key
=
None
expensive_char
=
char
=
n
()
expensive_char
=
char
=
n
()
...
@@ -1436,7 +1403,7 @@ def main():
...
@@ -1436,7 +1403,7 @@ def main():
matchrequest = REQUEST_PATTERN.match
matchrequest = REQUEST_PATTERN.match
if args.period is None:
if args.period is None:
next_period_data = ((x, y[4] * AUTO_PERIOD_COEF) for (x, y) in
next_period_data = ((x, y[4] * AUTO_PERIOD_COEF) for (x, y) in
sorted(period_parser.ite
ritems(), key=lambda x: x[1][4])).next
sorted(period_parser.ite
ms(), key=lambda x: x[1][4])).__next__
period, to_next_period = next_period_data()
period, to_next_period = next_period_data()
original_period = period
original_period = period
earliest_date = latest_date = None
earliest_date = latest_date = None
...
@@ -1540,7 +1507,7 @@ def main():
...
@@ -1540,7 +1507,7 @@ def main():
logfile = sys.stdin
logfile = sys.stdin
else:
else:
for opener, exc in FILE_OPENER_LIST:
for opener, exc in FILE_OPENER_LIST:
logfile = opener(filename,
_read_mode
, encoding=INPUT_ENCODING, errors=INPUT_ENCODING_ERROR_HANDLER)
logfile = opener(filename,
'
rt
'
, encoding=INPUT_ENCODING, errors=INPUT_ENCODING_ERROR_HANDLER)
try:
try:
logfile.readline()
logfile.readline()
except exc:
except exc:
...
@@ -1549,7 +1516,7 @@ def main():
...
@@ -1549,7 +1516,7 @@ def main():
logfile.seek(0)
logfile.seek(0)
break
break
else:
else:
logfile =
codecs.open(filename, _read_mode
, encoding=INPUT_ENCODING, errors=INPUT_ENCODING_ERROR_HANDLER)
logfile =
open(filename, 'r'
, encoding=INPUT_ENCODING, errors=INPUT_ENCODING_ERROR_HANDLER)
lineno = 0
lineno = 0
for lineno, line in enumerate(logfile, 1):
for lineno, line in enumerate(logfile, 1):
if show_progress and lineno % 5000 == 0:
if show_progress and lineno % 5000 == 0:
...
@@ -1572,7 +1539,7 @@ def main():
...
@@ -1572,7 +1539,7 @@ def main():
no_url_lines += 1
no_url_lines += 1
continue
continue
url = url_match.group('
url
')
url = url_match.group('
url
')
if url.startswith(
b
'
http
'):
if url.startswith('
http
'):
url = splithost(splittype(url)[1])[1]
url = splithost(splittype(url)[1])[1]
url = get_url_prefix(match, url)
url = get_url_prefix(match, url)
for site, prefix_match, action in site_list:
for site, prefix_match, action in site_list:
...
@@ -1608,7 +1575,7 @@ def main():
...
@@ -1608,7 +1575,7 @@ def main():
latest_date = rescale(latest_date)
latest_date = rescale(latest_date)
earliest_date = rescale(earliest_date)
earliest_date = rescale(earliest_date)
period_increase_start = time.time()
period_increase_start = time.time()
for site_data in per_site.
iter
values():
for site_data in per_site.values():
site_data.rescale(rescale, getDuration)
site_data.rescale(rescale, getDuration)
if show_progress:
if show_progress:
print('
done
(
%
s
)
' % timedelta(seconds=time.time()
print('
done
(
%
s
)
' % timedelta(seconds=time.time()
...
@@ -1633,9 +1600,10 @@ def main():
...
@@ -1633,9 +1600,10 @@ def main():
end_parsing_time = time.time()
end_parsing_time = time.time()
generator, out_encoding = format_generator[args.format]
generator, out_encoding = format_generator[args.format]
if args.out == '
-
':
if args.out == '
-
':
out = codecs.getwriter(out_encoding)(sys.stdout)
out = sys.stdout
out.reconfigure(encoding=out_encoding)
else:
else:
out =
codecs.
open(args.out, '
w
', encoding=out_encoding)
out = open(args.out, '
w
', encoding=out_encoding)
with out:
with out:
generator(out, out_encoding, per_site, args, default_site, {
generator(out, out_encoding, per_site, args, default_site, {
'
period
': period,
'
period
': period,
...
@@ -1662,10 +1630,11 @@ def main():
...
@@ -1662,10 +1630,11 @@ def main():
if __name__ == '
__main__
':
if __name__ == '
__main__
':
__resource_base = os.path.join(*os.path.split(__file__)[:-1])
__resource_base = os.path.join(*os.path.split(__file__)[:-1])
def getResource(name, encoding='
utf
-
8
'):
def getResource(name, encoding='
utf
-
8
'):
return codecs.
open(
with
open(
os.path.join(__resource_base, name),
os.path.join(__resource_base, name),
encoding=encoding,
encoding=encoding,
).read()
) as f:
return f.read()
main()
main()
...
...
apachedex/tests.py
View file @
ffdc722a
...
@@ -3,10 +3,10 @@ import sys
...
@@ -3,10 +3,10 @@ import sys
import
json
import
json
import
bz2
import
bz2
import
gzip
import
gzip
from
StringIO
import
StringIO
import
io
import
tempfile
import
tempfile
import
apachedex
import
apachedex
from
.
import
lzma
import
lzma
class
ApacheDEXTestCase
(
unittest
.
TestCase
):
class
ApacheDEXTestCase
(
unittest
.
TestCase
):
...
@@ -15,8 +15,10 @@ class ApacheDEXTestCase(unittest.TestCase):
...
@@ -15,8 +15,10 @@ class ApacheDEXTestCase(unittest.TestCase):
self
.
_original_sys_stdin
=
sys
.
stdin
self
.
_original_sys_stdin
=
sys
.
stdin
self
.
_original_sys_stderr
=
sys
.
stderr
self
.
_original_sys_stderr
=
sys
.
stderr
self
.
_original_sys_stdout
=
sys
.
stdout
self
.
_original_sys_stdout
=
sys
.
stdout
sys
.
stderr
=
StringIO
()
self
.
_stderr_bytes
=
io
.
BytesIO
()
sys
.
stdout
=
StringIO
()
sys
.
stderr
=
io
.
TextIOWrapper
(
self
.
_stderr_bytes
,
write_through
=
True
)
self
.
_stdout_bytes
=
io
.
BytesIO
()
sys
.
stdout
=
io
.
TextIOWrapper
(
self
.
_stdout_bytes
,
write_through
=
True
)
def
tearDown
(
self
):
def
tearDown
(
self
):
sys
.
argv
=
self
.
_original_sys_argv
sys
.
argv
=
self
.
_original_sys_argv
...
@@ -25,17 +27,31 @@ class ApacheDEXTestCase(unittest.TestCase):
...
@@ -25,17 +27,31 @@ class ApacheDEXTestCase(unittest.TestCase):
sys
.
stdout
=
self
.
_original_sys_stdout
sys
.
stdout
=
self
.
_original_sys_stdout
class
TestFiles
(
ApacheDEXTestCase
):
def
test
(
self
):
with
tempfile
.
NamedTemporaryFile
()
as
fin
,
tempfile
.
NamedTemporaryFile
()
as
fout
:
fin
.
write
(
b'''127.0.0.1 - - [14/Jul/2017:09:41:41 +0200] "GET / HTTP/1.1" 200 7499 "https://example.org/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 1754'''
)
fin
.
flush
()
sys
.
argv
=
[
'apachedex'
,
'--base=/'
,
fin
.
name
,
'--out'
,
fout
.
name
]
apachedex
.
main
()
fout
.
flush
()
fout
.
seek
(
0
)
self
.
assertIn
(
b"<html>"
,
fout
.
read
())
class
TestMalformedInput
(
ApacheDEXTestCase
):
class
TestMalformedInput
(
ApacheDEXTestCase
):
def
test_timestamp_mixed_in_timestamp
(
self
):
def
test_timestamp_mixed_in_timestamp
(
self
):
sys
.
argv
=
[
'apachedex'
,
'--base=/'
,
'-'
]
sys
.
argv
=
[
'apachedex'
,
'--base=/'
,
'-'
]
sys
.
stdin
=
StringIO
(
sys
.
stdin
=
io
.
StringIO
(
# this first line is valid, but second is not
# this first line is valid, but second is not
'''127.0.0.1 - - [14/Jul/2017:09:41:41 +0200] "GET / HTTP/1.1" 200 7499 "https://example.org/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 1754
'''127.0.0.1 - - [14/Jul/2017:09:41:41 +0200] "GET / HTTP/1.1" 200 7499 "https://example.org/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 1754
127.0.0.1 - - [14/Jul/2017:127.0.0.1 - - [14/Jul/2017:09:41:41 +0200] "GET / HTTP/1.1" 200 7499 "https://example.org/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 1754'''
)
127.0.0.1 - - [14/Jul/2017:127.0.0.1 - - [14/Jul/2017:09:41:41 +0200] "GET / HTTP/1.1" 200 7499 "https://example.org/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 1754'''
)
apachedex
.
main
()
apachedex
.
main
()
self
.
assertNotIn
(
'Malformed line at -:1'
,
sys
.
stderr
.
getvalue
())
self
.
assertNotIn
(
b'Malformed line at -:1'
,
self
.
_stderr_bytes
.
getvalue
())
self
.
assertIn
(
'Malformed line at -:2'
,
sys
.
stderr
.
getvalue
())
self
.
assertIn
(
b'Malformed line at -:2'
,
self
.
_stderr_bytes
.
getvalue
())
class
TestCharacterEncoding
(
ApacheDEXTestCase
):
class
TestCharacterEncoding
(
ApacheDEXTestCase
):
...
@@ -48,7 +64,7 @@ class TestCharacterEncoding(ApacheDEXTestCase):
...
@@ -48,7 +64,7 @@ class TestCharacterEncoding(ApacheDEXTestCase):
fin
.
flush
()
fin
.
flush
()
sys
.
argv
=
[
'apachedex'
,
'--base=/'
,
fin
.
name
,
'-f'
,
'json'
,
'-o'
,
fout
.
name
]
sys
.
argv
=
[
'apachedex'
,
'--base=/'
,
fin
.
name
,
'-f'
,
'json'
,
'-o'
,
fout
.
name
]
apachedex
.
main
()
apachedex
.
main
()
self
.
assertNotIn
(
'Malformed line'
,
sys
.
stderr
.
getvalue
())
self
.
assertNotIn
(
b'Malformed line'
,
self
.
_stderr_bytes
.
getvalue
())
with
open
(
fout
.
name
)
as
f
:
with
open
(
fout
.
name
)
as
f
:
self
.
assertTrue
(
json
.
load
(
f
))
self
.
assertTrue
(
json
.
load
(
f
))
...
@@ -74,7 +90,7 @@ class EncodedInputTestMixin:
...
@@ -74,7 +90,7 @@ class EncodedInputTestMixin:
fin
.
flush
()
fin
.
flush
()
sys
.
argv
=
[
'apachedex'
,
'--base=/'
,
fin
.
name
,
'-f'
,
'json'
,
'-o'
,
fout
.
name
]
sys
.
argv
=
[
'apachedex'
,
'--base=/'
,
fin
.
name
,
'-f'
,
'json'
,
'-o'
,
fout
.
name
]
apachedex
.
main
()
apachedex
.
main
()
self
.
assertNotIn
(
'Malformed line'
,
sys
.
stderr
.
getvalue
())
self
.
assertNotIn
(
b'Malformed line'
,
self
.
_stderr_bytes
.
getvalue
())
with
open
(
fout
.
name
)
as
f
:
with
open
(
fout
.
name
)
as
f
:
self
.
assertTrue
(
json
.
load
(
f
))
self
.
assertTrue
(
json
.
load
(
f
))
...
@@ -86,20 +102,15 @@ class TestBzip2Encoding(ApacheDEXTestCase, EncodedInputTestMixin):
...
@@ -86,20 +102,15 @@ class TestBzip2Encoding(ApacheDEXTestCase, EncodedInputTestMixin):
class
TestZlibEncoding
(
ApacheDEXTestCase
,
EncodedInputTestMixin
):
class
TestZlibEncoding
(
ApacheDEXTestCase
,
EncodedInputTestMixin
):
def
_getInputData
(
self
):
def
_getInputData
(
self
):
f
=
String
IO
()
f
=
io
.
Bytes
IO
()
with
gzip
.
GzipFile
(
mode
=
"w"
,
fileobj
=
f
)
as
gzfile
:
with
gzip
.
GzipFile
(
mode
=
"w"
,
fileobj
=
f
)
as
gzfile
:
gzfile
.
write
(
self
.
DEFAULT_LINE
)
gzfile
.
write
(
self
.
DEFAULT_LINE
)
return
f
.
getvalue
()
return
f
.
getvalue
()
if
lzma
is
not
None
:
class
TestLzmaEncoding
(
ApacheDEXTestCase
,
EncodedInputTestMixin
):
class
TestLzmaEncoding
(
ApacheDEXTestCase
,
EncodedInputTestMixin
):
def
_getInputData
(
self
):
def
_getInputData
(
self
):
return
lzma
.
compress
(
self
.
DEFAULT_LINE
)
return
lzma
.
compress
(
self
.
DEFAULT_LINE
)
else
:
class
TestLzmaEncoding
(
ApacheDEXTestCase
):
def
test
(
self
):
self
.
skipTest
(
"lzma not available"
)
class
TestTimeEnconding
(
ApacheDEXTestCase
):
class
TestTimeEnconding
(
ApacheDEXTestCase
):
...
@@ -107,7 +118,7 @@ class TestTimeEnconding(ApacheDEXTestCase):
...
@@ -107,7 +118,7 @@ class TestTimeEnconding(ApacheDEXTestCase):
def
test_seconds_timing
(
self
):
def
test_seconds_timing
(
self
):
with
tempfile
.
NamedTemporaryFile
()
as
fout
:
with
tempfile
.
NamedTemporaryFile
()
as
fout
:
sys
.
argv
=
[
'apachedex'
,
'--base=/'
,
'-'
,
'--logformat'
,
'%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i" %T'
,
'-f'
,
'json'
,
'-o'
,
fout
.
name
]
sys
.
argv
=
[
'apachedex'
,
'--base=/'
,
'-'
,
'--logformat'
,
'%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i" %T'
,
'-f'
,
'json'
,
'-o'
,
fout
.
name
]
sys
.
stdin
=
StringIO
(
sys
.
stdin
=
io
.
StringIO
(
'''127.0.0.1 - - [14/Jul/2017:09:41:41 +0200] "GET / HTTP/1.1" 200 7499 "https://example.org/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 1'''
)
'''127.0.0.1 - - [14/Jul/2017:09:41:41 +0200] "GET / HTTP/1.1" 200 7499 "https://example.org/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 1'''
)
apachedex
.
main
()
apachedex
.
main
()
...
@@ -119,7 +130,7 @@ class TestTimeEnconding(ApacheDEXTestCase):
...
@@ -119,7 +130,7 @@ class TestTimeEnconding(ApacheDEXTestCase):
def
test_milliseconds_timing
(
self
):
def
test_milliseconds_timing
(
self
):
with
tempfile
.
NamedTemporaryFile
()
as
fout
:
with
tempfile
.
NamedTemporaryFile
()
as
fout
:
sys
.
argv
=
[
'apachedex'
,
'--base=/'
,
'-'
,
'--logformat'
,
'%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i" %D'
,
'-f'
,
'json'
,
'-o'
,
fout
.
name
]
sys
.
argv
=
[
'apachedex'
,
'--base=/'
,
'-'
,
'--logformat'
,
'%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i" %D'
,
'-f'
,
'json'
,
'-o'
,
fout
.
name
]
sys
.
stdin
=
StringIO
(
sys
.
stdin
=
io
.
StringIO
(
'''127.0.0.1 - - [14/Jul/2017:09:41:41 +0200] "GET / HTTP/1.1" 200 7499 "https://example.org/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 1000000'''
)
'''127.0.0.1 - - [14/Jul/2017:09:41:41 +0200] "GET / HTTP/1.1" 200 7499 "https://example.org/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 1000000'''
)
apachedex
.
main
()
apachedex
.
main
()
...
@@ -131,7 +142,7 @@ class TestTimeEnconding(ApacheDEXTestCase):
...
@@ -131,7 +142,7 @@ class TestTimeEnconding(ApacheDEXTestCase):
def
test_microseconds_timing
(
self
):
def
test_microseconds_timing
(
self
):
with
tempfile
.
NamedTemporaryFile
()
as
fout
:
with
tempfile
.
NamedTemporaryFile
()
as
fout
:
sys
.
argv
=
[
'apachedex'
,
'--base=/'
,
'-'
,
'--logformat'
,
'%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i" %{ms}T'
,
'-f'
,
'json'
,
'-o'
,
fout
.
name
]
sys
.
argv
=
[
'apachedex'
,
'--base=/'
,
'-'
,
'--logformat'
,
'%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i" %{ms}T'
,
'-f'
,
'json'
,
'-o'
,
fout
.
name
]
sys
.
stdin
=
StringIO
(
sys
.
stdin
=
io
.
StringIO
(
'''127.0.0.1 - - [14/Jul/2017:09:41:41 +0200] "GET / HTTP/1.1" 200 7499 "https://example.org/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 1000
'''127.0.0.1 - - [14/Jul/2017:09:41:41 +0200] "GET / HTTP/1.1" 200 7499 "https://example.org/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 1000
'''
)
'''
)
...
...
setup.py
View file @
ffdc722a
...
@@ -64,14 +64,13 @@ setup(
...
@@ -64,14 +64,13 @@ setup(
long_description
=
".. contents::
\
n
\
n
"
+
description
,
long_description
=
".. contents::
\
n
\
n
"
+
description
,
author
=
'Vincent Pelletier'
,
author
=
'Vincent Pelletier'
,
author_email
=
'vincent@nexedi.com'
,
author_email
=
'vincent@nexedi.com'
,
url
=
'http
://git.erp5.org/gitweb
/apachedex.git'
,
url
=
'http
s://lab.nexedi.com/nexedi
/apachedex.git'
,
license
=
'GPL 2+'
,
license
=
'GPL 2+'
,
platforms
=
[
'any'
],
platforms
=
[
'any'
],
classifiers
=
[
classifiers
=
[
'Intended Audience :: Developers'
,
'Intended Audience :: Developers'
,
'License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)'
,
'License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)'
,
'Operating System :: OS Independent'
,
'Operating System :: OS Independent'
,
'Programming Language :: Python :: 2.7'
,
'Programming Language :: Python :: 3'
,
'Programming Language :: Python :: 3'
,
'Programming Language :: Python :: Implementation :: PyPy'
,
'Programming Language :: Python :: Implementation :: PyPy'
,
'Programming Language :: Python :: Implementation :: CPython'
,
'Programming Language :: Python :: Implementation :: CPython'
,
...
@@ -90,5 +89,4 @@ setup(
...
@@ -90,5 +89,4 @@ setup(
},
},
test_suite
=
'apachedex.tests'
,
test_suite
=
'apachedex.tests'
,
zip_safe
=
True
,
zip_safe
=
True
,
use_2to3
=
True
,
)
)
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