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
69abce9a
Commit
69abce9a
authored
Jun 10, 2002
by
Shane Hathaway
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merged shane-activity-monitoring-branch.
parent
1b063f12
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
279 additions
and
4 deletions
+279
-4
lib/python/App/ApplicationManager.py
lib/python/App/ApplicationManager.py
+4
-1
lib/python/App/CacheManager.py
lib/python/App/CacheManager.py
+124
-2
lib/python/App/dtml/activity.dtml
lib/python/App/dtml/activity.dtml
+84
-0
lib/python/App/www/load_bar.gif
lib/python/App/www/load_bar.gif
+0
-0
lib/python/App/www/store_bar.gif
lib/python/App/www/store_bar.gif
+0
-0
lib/python/App/www/transparent_bar.gif
lib/python/App/www/transparent_bar.gif
+0
-0
lib/python/HelpSys/HelpSys.py
lib/python/HelpSys/HelpSys.py
+1
-1
lib/python/Products/OFSP/help/Database-Management_Activity.stx
...ython/Products/OFSP/help/Database-Management_Activity.stx
+62
-0
lib/python/Zope/__init__.py
lib/python/Zope/__init__.py
+4
-0
No files found.
lib/python/App/ApplicationManager.py
View file @
69abce9a
...
...
@@ -11,7 +11,7 @@
#
##############################################################################
__doc__
=
"""System management components"""
__version__
=
'$Revision: 1.7
8
$'
[
11
:
-
2
]
__version__
=
'$Revision: 1.7
9
$'
[
11
:
-
2
]
import
sys
,
os
,
time
,
Globals
,
Acquisition
,
os
,
Undo
...
...
@@ -49,6 +49,8 @@ class DatabaseManager(Fake, SimpleItem.Item, Acquisition.Implicit):
(
{
'label'
:
'Database'
,
'action'
:
'manage_main'
,
'help'
:(
'OFSP'
,
'Database-Management_Database.stx'
)},
{
'label'
:
'Activity'
,
'action'
:
'manage_activity'
,
'help'
:(
'OFSP'
,
'Database-Management_Activity.stx'
)},
{
'label'
:
'Cache Parameters'
,
'action'
:
'manage_cacheParameters'
,
'help'
:(
'OFSP'
,
'Database-Management_Cache-Parameters.stx'
)},
{
'label'
:
'Flush Cache'
,
'action'
:
'manage_cacheGC'
,
...
...
@@ -58,6 +60,7 @@ class DatabaseManager(Fake, SimpleItem.Item, Acquisition.Implicit):
# These need to be here rather to make tabs work correctly. This
# needs to be revisited.
manage_activity
=
Globals
.
DTMLFile
(
'dtml/activity'
,
globals
())
manage_cacheParameters
=
Globals
.
DTMLFile
(
'dtml/cacheParameters'
,
globals
())
manage_cacheGC
=
Globals
.
DTMLFile
(
'dtml/cacheGC'
,
globals
())
...
...
lib/python/App/CacheManager.py
View file @
69abce9a
...
...
@@ -13,10 +13,11 @@
__doc__
=
'''Cache management support
$Id: CacheManager.py,v 1.2
4 2002/03/27 10:14:00 htrd
Exp $'''
__version__
=
'$Revision: 1.2
4
$'
[
11
:
-
2
]
$Id: CacheManager.py,v 1.2
5 2002/06/10 20:20:43 shane
Exp $'''
__version__
=
'$Revision: 1.2
5
$'
[
11
:
-
2
]
import
Globals
,
time
,
sys
from
DateTime
import
DateTime
class
CacheManager
:
"""Cache management mix-in
...
...
@@ -25,10 +26,15 @@ class CacheManager:
_cache_size
=
400
_vcache_age
=
60
_vcache_size
=
400
_history_length
=
3600
# Seconds
manage_cacheParameters
=
Globals
.
DTMLFile
(
'dtml/cacheParameters'
,
globals
())
manage_cacheGC
=
Globals
.
DTMLFile
(
'dtml/cacheGC'
,
globals
())
transparent_bar
=
Globals
.
ImageFile
(
'www/transparent_bar.gif'
,
globals
())
store_bar
=
Globals
.
ImageFile
(
'www/store_bar.gif'
,
globals
())
load_bar
=
Globals
.
ImageFile
(
'www/load_bar.gif'
,
globals
())
def
cache_length
(
self
):
try
:
db
=
self
.
_p_jar
.
db
()
except
:
...
...
@@ -185,6 +191,9 @@ class CacheManager:
db
.
setCacheDeactivateAfter
(
self
.
_cache_age
)
db
.
setVersionCacheSize
(
self
.
_vcache_size
)
db
.
setVersionCacheDeactivateAfter
(
self
.
_vcache_age
)
am
=
self
.
_getActivityMonitor
()
if
am
is
not
None
:
am
.
setHistoryLength
(
self
.
_history_length
)
def
cache_detail
(
self
,
REQUEST
=
None
):
"""
...
...
@@ -239,5 +248,118 @@ class CacheManager:
# raw
return
detail
def
_getActivityMonitor
(
self
):
db
=
self
.
_p_jar
.
db
()
if
not
hasattr
(
db
,
'getActivityMonitor'
):
return
None
am
=
db
.
getActivityMonitor
()
if
am
is
None
:
return
None
return
am
def
getHistoryLength
(
self
):
am
=
self
.
_getActivityMonitor
()
if
am
is
None
:
return
0
return
am
.
getHistoryLength
()
def
manage_setHistoryLength
(
self
,
length
,
REQUEST
=
None
):
"""Change the length of the activity monitor history.
"""
am
=
self
.
_getActivityMonitor
()
length
=
int
(
length
)
if
length
<
0
:
raise
ValueError
,
'length can not be negative'
if
am
is
not
None
:
am
.
setHistoryLength
(
length
)
self
.
_history_length
=
length
# Restore on startup
if
REQUEST
is
not
None
:
response
=
REQUEST
[
'RESPONSE'
]
response
.
redirect
(
REQUEST
[
'URL1'
]
+
'/manage_activity'
)
def
getActivityChartData
(
self
,
segment_height
,
REQUEST
=
None
):
"""Returns information for generating an activity chart.
"""
am
=
self
.
_getActivityMonitor
()
if
am
is
None
:
return
None
if
REQUEST
is
not
None
:
start
=
float
(
REQUEST
.
get
(
'chart_start'
,
0
))
end
=
float
(
REQUEST
.
get
(
'chart_end'
,
0
))
divisions
=
int
(
REQUEST
.
get
(
'chart_divisions'
,
10
))
analysis
=
am
.
getActivityAnalysis
(
start
,
end
,
divisions
)
else
:
analysis
=
am
.
getActivityAnalysis
()
total_load_count
=
0
total_store_count
=
0
limit
=
0
divs
=
[]
for
div
in
analysis
:
total_store_count
=
total_store_count
+
div
[
'stores'
]
total_load_count
=
total_load_count
+
div
[
'loads'
]
sum
=
div
[
'stores'
]
+
div
[
'loads'
]
if
sum
>
limit
:
limit
=
sum
if
analysis
:
segment_time
=
analysis
[
0
][
'end'
]
-
analysis
[
0
][
'start'
]
else
:
segment_time
=
0
for
div
in
analysis
:
stores
=
div
[
'stores'
]
if
stores
>
0
:
store_len
=
max
(
int
(
segment_height
*
stores
/
limit
),
1
)
else
:
store_len
=
0
loads
=
div
[
'loads'
]
if
loads
>
0
:
load_len
=
max
(
int
(
segment_height
*
loads
/
limit
),
1
)
else
:
load_len
=
0
t
=
div
[
'end'
]
-
analysis
[
-
1
][
'end'
]
# Show negative numbers.
if
segment_time
>=
3600
:
# Show hours.
time_offset
=
'%dh'
%
(
t
/
3600
)
elif
segment_time
>=
60
:
# Show minutes.
time_offset
=
'%dm'
%
(
t
/
60
)
elif
segment_time
>=
1
:
# Show seconds.
time_offset
=
'%ds'
%
t
else
:
# Show fractions.
time_offset
=
'%.2fs'
%
t
divs
.
append
({
'store_len'
:
store_len
,
'load_len'
:
load_len
,
'trans_len'
:
max
(
segment_height
-
store_len
-
load_len
,
0
),
'store_count'
:
div
[
'stores'
],
'load_count'
:
div
[
'loads'
],
'start'
:
div
[
'start'
],
'end'
:
div
[
'end'
],
'time_offset'
:
time_offset
,
})
if
analysis
:
start_time
=
DateTime
(
divs
[
0
][
'start'
]).
aCommonZ
()
end_time
=
DateTime
(
divs
[
-
1
][
'end'
]).
aCommonZ
()
else
:
start_time
=
''
end_time
=
''
res
=
{
'start_time'
:
start_time
,
'end_time'
:
end_time
,
'divs'
:
divs
,
'total_store_count'
:
total_store_count
,
'total_load_count'
:
total_load_count
,
}
return
res
Globals
.
default__class_init__
(
CacheManager
)
lib/python/App/dtml/activity.dtml
0 → 100644
View file @
69abce9a
<dtml-var manage_page_header>
<dtml-var manage_tabs>
<h3>Recent Database Activity</h3>
<dtml-with expr="getActivityChartData(200, REQUEST)" mapping>
<table>
<tr>
<th valign="top">Keep History (seconds)</th>
<td>
<form method="POST" action="&dtml-URL1;/manage_setHistoryLength">
<input type="text" name="length" value="&dtml-getHistoryLength;" />
<input type="submit" name="submit" value="Save changes" />
</form>
</td>
</tr>
<tr>
<th valign="top">Displayed Range</th>
<td>&dtml-start_time; to<br />
&dtml-end_time;</td>
</tr>
<tr>
<th></th>
<td>
<form method="GET" action="&dtml-URL;">
<input type="submit" name="submit" value="Show current chart" />
</form>
</td>
</tr>
</table>
<p></p>
<div align="center">
<table style="border: solid thin black;">
<tr>
<td></td>
<dtml-in divs mapping>
<dtml-let url="REQUEST['URL'] + ('?chart_start=%s&chart_end=%s'
% (start, end))">
<td height="200" width="32"><a href="&dtml-url;"><dtml-if
trans_len><img src="transparent_bar" width="32"
height="&dtml-trans_len;" border="0" /><br /></dtml-if><dtml-if
store_len><img src="store_bar" width="32"
height="&dtml-store_len;" border="0" /><br /></dtml-if><dtml-if
load_len><img src="load_bar" width="32"
height="&dtml-load_len;" border="0" /></dtml-if></a></td>
</dtml-let>
</dtml-in>
</tr>
<tr>
<th align="left"><font color="#ff0000">Object stores</font></th>
<dtml-in divs mapping>
<td align="right"><dtml-let url="REQUEST['URL'] +
('?chart_start=%s&chart_end=%s'
% (start, end))"><a href="&dtml-url;"><font
color="#ff0000">&dtml-store_count;</font></a></dtml-let></td>
</dtml-in>
<th align="left"> Total:
<font color="#ff0000">&dtml-total_store_count;</font>
</th>
</tr>
<tr>
<th align="left" valign="top"><font color="#000080">Object loads</font></th>
<dtml-in divs mapping>
<td align="right"><dtml-let url="REQUEST['URL'] +
('?chart_start=%s&chart_end=%s'
% (start, end))"><a href="&dtml-url;"><font
color="#000080">&dtml-load_count;</font></a></dtml-let><br />
<font size="-2">&dtml-time_offset;</font></td>
</dtml-in>
<th align="left" valign="top"> Total:
<font color="#000080">&dtml-total_load_count;</font>
</th>
</tr>
</table>
</div>
</dtml-with>
<dtml-var manage_page_footer>
lib/python/App/www/load_bar.gif
0 → 100644
View file @
69abce9a
68 Bytes
lib/python/App/www/store_bar.gif
0 → 100644
View file @
69abce9a
68 Bytes
lib/python/App/www/transparent_bar.gif
0 → 100644
View file @
69abce9a
68 Bytes
lib/python/HelpSys/HelpSys.py
View file @
69abce9a
...
...
@@ -105,7 +105,7 @@ class HelpSys(Acquisition.Implicit, ObjectManager, Item, Persistent):
script
=
'window.open(
\
'
%s
\
'
,
\
'
zope_help
\
'
,
\
'
width=600,'
\
'height=500,menubar=yes,toolbar=yes,scrollbars=yes,'
\
'resizable=yes
\
'
)
.focus()
; return false;'
%
help_url
'resizable=yes
\
'
); return false;'
%
help_url
h_link
=
'<a href="%s" onClick="%s" onMouseOver="window.status='
\
'
\
'
Open online help
\
'
; return true;" onMouseOut="'
\
...
...
lib/python/Products/OFSP/help/Database-Management_Activity.stx
0 → 100644
View file @
69abce9a
Database Management - Activity
Description
This view displays activity in the ZODB over a period of time.
It shows how many objects were loaded and stored. You can use
this information to determine the optimal memory cache size for
your Zope application. You can also use it to discover
applications that write to the database too often.
Information
'Keep History' -- Lets you define how many seconds of history
to keep for analysis. 3600 is one hour. 86400 is one day.
Note that in the current implementation, analysis data is
kept only in memory and is never stored to disk, so each time
you restart, you lose the historical information.
'Displayed Range' -- Tells you what period of time is displayed
by the chart.
'Show current chart' -- Redisplays the chart for the current
time.
The chart contains a bar graph. The rightmost bar shows the
most recent activity. The red portion indicates the number of
objects stored and the blue portion indicates the number of
objects loaded during that time period. To the right of the
graph there is a total.
If you click on a bar, the chart will zoom in on the time
period for just that bar. You will see the details of the
activity during that short time period. Click the "Show current
chart" button to return to the chart for the current time.
How to use this information
Once Zope has loaded enough objects, the ZODB cache consistently
keeps in the cache the number of objects you specify under the
"Cache Parameters" tab. Because the cache size is so consistent
and ZODB is so transparent to both the user and
application developer, Zope applications can invisibly develop a
performance problem by loading objects from ZODB on every request.
Also, if the cache size is set too high, Zope will consume more
RAM than it needs. You need to find a good balance that fits
your site. If the bar chart shows a large number of objects being
loaded all the time, increase the cache size, which will increase
memory usage but should also increase performance. If the
chart shows little activity even though the site is visited
frequently, you can reduce the cache size so Zope will consume less
RAM.
As your site changes, its cache size requirements may change also,
so remember to make adjustments over time.
If the graph shows a lot of writes (a significant portion of red),
some application or product may be writing to the database too
frequently. Check the "undo" log for clues. Note that the activity
graph does not show activity in mounted databases, so objects loaded
and stored by the sessioning machinery are not counted in the graph.
lib/python/Zope/__init__.py
View file @
69abce9a
...
...
@@ -47,6 +47,10 @@ else:
Globals
.
BobobaseName
=
DB
.
getName
()
sys
.
modules
[
'Zope.custom_zodb'
]
=
m
if
DB
.
getActivityMonitor
()
is
None
:
from
ZODB.ActivityMonitor
import
ActivityMonitor
DB
.
setActivityMonitor
(
ActivityMonitor
())
Globals
.
DB
=
DB
# Ick, this is temporary until we come up with some registry
# Hook for providing multiple transaction object manager undo support:
...
...
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