Uploaded image for project: 'Apache Freemarker'
  1. Apache Freemarker
  2. FREEMARKER-120

Hook to collect which members are accessed on runtime

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Trivial
    • Resolution: Implemented
    • 2.3.29
    • 2.3.30
    • engine
    • None

    Description

      Problem description

      We would like to collect metrics which counts which Objects and methods are called by templates.
       

      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.).

      Example of possible metrics output

       

      com.company.MyClass#getA()=1 
      com.company.MyClass#getB(String)=567 
      com.company.Otherclass#getA(String, String)=134  

       
      etc. 
      For example Hibernate has a similar in-built mechanism which collects metrics.(https://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/stat/Statistics.html)

      This is a bit too much for freemarker to have this built-in, that's why a hook would be enough.
        
       

       Suggestion

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

      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
      }
      

      See example https://github.com/chrisrueger/freemarker/commit/804b3d99188e1dbb00fd03f8fe120515b17bbbca

       

      Possible example implementation which uses this hook to collect metrics

      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());
      	}
      
      }

       

      Attachments

        Activity

          People

            Unassigned Unassigned
            mephiztophelez Christoph Rueger
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: