avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Berin Loritsch <blorit...@apache.org>
Subject Re: [RT] Profiler class thoughts
Date Thu, 28 Feb 2002 14:42:15 GMT
:) At Marcus' prodding, I will add in my thoughts now.

The first thing I want to say is that I started the Profiler interfaces
a while back when I had more time to devote to Avalon.  They are based
on Matt Welsh's work with the Sandstorm server.  I cleaned up the API,
and added the ability to have multiple profile points within an object.
Furthermore, I intended for the system to be heirarchical in nature so
that the containers could manage what gets reported, and what doesn't.

Marcus brought up some good points in that Instrumenting your code is
more the concern of the developer or administrator.  When you are tuning
your system, you want to be able to be able to zero in on the
information you really want.

Therefore, the choice of what gets reported is ultimately the result of
the Report itself.  Also, the starting and stopping of profiling should
be done by the report object.  In some cases, you want to start right
away, and collect information for the life of the development run.  In
other cases, you only want certain time slices.

Furthermore, the Profiler (or better named Instrumentor) should be the
liaison that collects all the Profilables and profile points.  The
Report should be able to communicate with the Intrumentor (or Profiler)
to determine which of the profile points we want to examine.

If you keep the spirit of what I just laid out in tact, I would be happy
to let you guys loose on the "profiler" code.  Just keep us appraised
as to your progress.

Leif Mortenson wrote:
> 
> 
> Marcus Crafter wrote:
> 
>> Hi All,
>>
>>     Hope all is well.
>>
>>     Over the weekend I spent some time playing around with the
>>     Profiler interfaces in scratchpad. I've come up with an initial
>>     version of the code, but during implementation it got me
>>     thinking about future ideas.
>>
>>     I had a couple of thoughts, and I'd be interested in any comments, as
>>     they require changes to the current API.
>>     
>>     Bear with me, hopefully this is clear :)
>>
>>     The current API has the Profiler class in control. It does the
>>     sampling, and pushes out the data to the reporting implementation.
>>     This model has some disadvantages:
>>
>>     1. Data is pushed out to the reporting engine, which means we can't
>>     write any on-demand reporting classes (eg. 
>> UpdatableSwingProfileReport,
>>     ServletProfileReport, etc). :(
>>
>>
>>
>>     2. If we enhance Profiler to support multiple reports, all reports
>>     will receive sample data at the same time interval. :(
>>
>>     3. For large scale applications where sampling time is not 
>> negligable,
>>     samples and the timestamp value can be inaccurate when printed. :(
>>
>>     4. The reporting object must be initialized with the profilable 
>> object
>>     names and profile point names before any sampling takes place so
>>     it knows how to label information.
>>
>>     This means it requires some voodoo code to dynamically add
>>     Profilables to the system without restarting the Profiler. :(
>>
>>     On an implementation level, it means the reporting engine must
>>     maintain a second (internal) copy/reference of each Profilable's
>>     names and their profile points names (the first copies are in the
>>     Profilable objects themselves), and maintain relationship hierarchies
>>     between any child profilable objects.
>>
>>     (I found this to be a real mess to implement as 
>> ProfileReport.addGroup()
>>     does not distinguish between profile point names and profilable 
>> object
>>     names)
>>
>>     We can remove all these limitations and reduce implementation
>>     complexity by changing the way sampling takes place.
>>
>>     Instead of implementing a push model where the profiler samples
>>     data and pushes it out to the reporting implementation, we could
>>     consider a pull model, where the reporting implementation does
>>     the sampling directly.
>>
> Here are some of my ideas on how to do this.  Some of it is in line with 
> what you are making, and others
> are not.  :-)
> 
> Our old product includes some simple profiling that was always enabled 
> to keep track of things like memory
> usage, connection counts, request counts etc.  These profile points 
> could then be requested by any report at
> any time in the future.
> 
> Is what I would really love to see the Profiler do is the following:   
> When any component that implements
> Profilable is initialized, it will go through and register any profile 
> points that it has available.  Then the Profile
> Manager would look for these points in a configuration like the following:
> 
> -----------------
> <profiler>
>    <categories>
>        <category name="history-stats">
>            <data key="min" type="min">
>                <history type="full-data"/>
>            </data>
>            <data key="max" type="max">
>                <history type="full-data"/>
>            </data>
>            <data key="average" type="average">
>                <history type="full-data"/>
>            </data>
>        </category>
> 
>        <category name="history-count">
>            <data key="count" type="count">
>                <history type="full-data"/>
>            </data>
>        </category>
> 
>        <category name="debug">
>            <data key="count" type="count"/>
>        </category>
>    </categories>
> 
>    <history-types>
>        <history-type name="full-data">
>            <!-- 1 second interval for 10 minutes -->
>            <storage interval="1000" size="600"/>
>            <!-- 1 minute interval for 1 hour -->
>            <storage interval="60000" size="3600000"/>
>            <!-- 1 hour interval for 1 day -->
>            <storage interval="3600000" size="86400000"/>
>        </history-type>
>    </history-types>
> </profiler>
> 
> <components>
>    <my-server>
>        <profile-point name="memory" category="standard" 
> history-type="history-stats"/>
>        <profile-point name="connections" category="standard" 
> history-type="history-count"/>
>        <profile-point name="getObjCalls" category="debug"/>
>    </my-server>
> </components>
> -----------------
> 
> This configuration defines a my-server component which has 3 profile 
> ponts.  The first two:
> memory and connections are configured to be "pull" datapoints because 
> they specify
> history.  The third point, getObjCalls, does not.  Its profile 
> information would not be collected
> until the a report needs the data.
> 
> The profile points should be used like the following to avoid 
> unnecessary CPU usage.  Modeled
> after the logger code.)
> 
> ---
> if (m_getObjCallsProfilePoint.isListening()) {
>    m_getObjCallsProfilePoint.increment();
> }
> ---
> or
> ---
> m_connectionCount++;
> if (m_connectionsProfilePoint.isListening()) {
>    m_connectionsProfilePoint.setPoint(m_connectionCount);
> }
> ---
> 
> The isListening method for any profile point would be false whenever 
> nobody was listening.
> 
> The history data would be implemented as a report so it would cause the 
> isListening method
> to return true.  By doing it this way, the component would not need to 
> worry about whether
> or not history was being used.
> 
> A report could either be registered as a listener or the ProfileManager 
> could be queried for
> a specific data set using history if available.  If the profile point 
> does not maintain history, then
> the data set would just be empty.
> 
> Its getting late, so I may not be making too much sense.  I'll go back 
> and look over what you
> have checked in and get my thoughts strait in the morning :-)
> 
> Cheers,
> Leif
> 
>>
>>
>>     This fixes all of the above listed disadvantages, and also
>>     makes implementation much easier.
>>     
>>     At the interface level, we would have to change ProfileReport to be
>>     something like:
>>
>>     interface ProfileReport     {
>>         void startReport();
>>         void endReport();
>>         void addProfilable( Profilable profilable );
>>         void sample();
>>     }
>>
>>     Where 'startReport' would signal the reporting engine it can
>>     being sampling.
>>     
>>     Since the reporting class does the sampling, it can be made
>>     configurable with sampling times (and/or support on-demand
>>     sampling), etc.
>>     
>>     Since it maintains references directly to each profilable, supporting
>>     dynamic's is easy, and the report also doesn't need to maintain any
>>     group/subgroup names/references.
>>
>>     Also, since sampling is done by the reporting class when the
>>     data is needed it's more likely to be accurate in large scale
>>     environments.
>>
>>     To support multiple reports we'd need to change Profiler so it
>>     had:
>>
>>     interface Profiler
>>     {
>>         void addReport( ProfileReport report );
>>     }
>>
>>     Instead of just 'report(...)', and perhaps consider some
>>     'remove' methods.
>>
>>     Hopefully that's understandable, please feel free to ask any
>>     questions.
>>
>>     Thoughts, comments ?
>>
>>     Cheers,
>>
>>     Marcus
>>
> 
> 
> 
> -- 
> To unsubscribe, e-mail:   
> <mailto:avalon-dev-unsubscribe@jakarta.apache.org>
> For additional commands, e-mail: 
> <mailto:avalon-dev-help@jakarta.apache.org>
> 
> 



-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


--
To unsubscribe, e-mail:   <mailto:avalon-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-dev-help@jakarta.apache.org>


Mime
View raw message