Christoph Rueger created FREEMARKER-120:
-------------------------------------------

             Summary: Hook to collect which members are accessed on runtime
                 Key: FREEMARKER-120
                 URL: https://issues.apache.org/jira/browse/FREEMARKER-120
             Project: Apache Freemarker
          Issue Type: Improvement
          Components: engine
    Affects Versions: 2.3.29
            Reporter: Christoph Rueger


h2. Problem description
We would like to collect metrics which counts which Objects and methods are 
called by templates.
 
h2. Why?

We have lots of FM-templates which are provided by users (not developers). 
Collecting metrics about method invocations would allow us to track what users 
are doing in templates, find out about about which methods are used how often 
(e.g. to determine potential for performance optimizations or detect unused 
methods (potential dead code)). Furthermore it allows to detect malicious usage 
(e.g. attempts to call "dangerous" methods on objects which were are accessible 
in templates etc.).
h3. Example of possible metrics output
 
{code:java}
com.company.MyClass#getA()=1 
com.company.MyClass#getB(String)=567 
com.company.Otherclass#getA(String, String)=134  {code}
 
etc. 
I know this e.g. from Hibernate which could be enabled / disabled 
([https://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/stat/Statistics.html])
  
 
h3.  Suggestion

It would be great if we e.g. could just override a method / hook in a Custom 
ObjectWrapper.


{code:java}

Could be specified in BeansWrapper.java and called from 
freemarker.ext.beans.BeansWrapper.invokeMethod(Object, Method, Object[]) just 
before the actual method invocation.

/**
     * This hook can be used by subclasses
     * e.g. for statistics about method invokation
     * (which methods get called on which objects how often).
     * 
     * @param object
     * @param method
     * @param args
     */
    protected void logMethodInvocation(Object object, Method method, Object[] 
args) {
        // TODO Auto-generated method stub
}
{code}
See example 
[https://github.com/chrisrueger/freemarker/commit/804b3d99188e1dbb00fd03f8fe120515b17bbbca]

 

*Possible implementation*
{code:java}
public class MyObjectWrapper extends SimpleObjectWrapper{
        
        private AtomicLongMap<String> methodStats = AtomicLongMap.create();


        public MyObjectWrapper(Version version) {
                super(version);


        @Override
        protected void logMethodInvocation(Object object, Method method, 
Object[] args) {
                
methodStats.incrementAndGet(object.getClass().getName()+"#"+method.getName());
        }

}{code}
 



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to