1

Any idea how to do what the title says? Only thing I found was on the original Velocity site, and I don't think

ve.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
    "org.apache.velocity.runtime.log.Log4JLogChute" );

ve.setProperty("runtime.log.logsystem.log4j.logger",
   LOGGER_NAME);

will work wonderfully well on .NET. I am using log4net, which should make it quite easy, but the documentation on NVelocity is really a mess.

ghallas
  • 285
  • 2
  • 14
  • I know this is not helpful, but the logging implementation is an utter mess inside NVelocity. I could never get it working properly, let alone with log4net. – Deleted Sep 01 '11 at 12:54
  • you 're right, it isn't helpful :) but thanx for helping consolidate my frustration – ghallas Sep 01 '11 at 13:18

2 Answers2

1

Implement NVelocity.Runtime.Log.ILogSystem (you could write a simple implementation that bridges to log4net) and set this impl type in the property RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS

How I got this information:

  1. Get the code.
  2. Search for "log" in the codebase
  3. Discover the classes in NVelocity.Runtime.Log.
  4. Read those classes' source, they're very simple and thoroughly documented.
Mauricio Scheffer
  • 98,863
  • 23
  • 192
  • 275
  • you make me look lazy... thanks for the detailed suggestions/instructions, still... I have Engine.SetProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, typeof(TemplateLogger)); in my NVelocityControl constructor, but there's no access to my TemplateLogger class's LogVelocityMessage method – ghallas Sep 01 '11 at 13:47
  • @ghallas: I don't know what's NVelocityControl or TemplateLogger, but you have to use the fully qualified type name: `typeof(TemplateLogger).AssemblyQualifiedName` – Mauricio Scheffer Sep 01 '11 at 13:52
  • sorry, I got carried away. TemplateLogger is of course my simple implementation of ILogSystem, NVelocityControl is just a class using the VelocityEngine. Thanx for the help. Just a personal opinion though, the SetProperty(string key, object value) isn't the most handy thing to use for things like this, plus if I have to fork every API I use to do s'thing like setting up logging, I 'd be spending more time on GitHub than on my Visual Studio. Still, much appreciation – ghallas Sep 01 '11 at 14:12
  • @ghallas: I invite you to fork the code and improve this. If you have any doubts, feel free to drop by the Castle dev list: http://groups.google.com/group/castle-project-devel – Mauricio Scheffer Sep 01 '11 at 14:45
  • @ghallas: BTW you don't need to fork the repository just to browse the code, in fact you don't even need to have git installed, github offers zipballs of the code. – Mauricio Scheffer Sep 01 '11 at 14:48
  • @ghallas: also, I like to keep around the source code of most of the open source projects I use, for quick lookup like this one, and I recommend you to do the same. – Mauricio Scheffer Sep 01 '11 at 14:48
  • Thanx for the invite, but I have my hands full, all four of them. No doubts on the quality of the code, it's just that all this just feels pretty Java-like (no wonder). – ghallas Sep 01 '11 at 14:57
1

Update:

Currently, NVelocity does not support logging. The initializeLogger() and Log() methods in RuntimeInstance Class are commented out.

If you need to log, uncomment the two methods, add a private ILogSystem logSystem; property

Here's our on-the-fly implementation:

public class RuntimeInstance : IRuntimeServices
{
    private ILogSystem logSystem;
    ...
    ...
    private void initializeLogger()
    {
    logSystem = LogManager.CreateLogSystem(this);

    }
    ...
    ...
    private void Log(LogLevel level, Object message)
    {
    String output = message.ToString();

    logSystem.LogVelocityMessage(level, output);
    }
    ...
}

Then, we implemented ILogSystem for log4net

using log4net;
using NVelocity.Runtime;
using NVelocity.Runtime.Log;

namespace Services.Templates
{
    public class Log4NetILogSystem : ILogSystem
    {
        private readonly ILog _log;

        public Log4NetILogSystem(ILog log )
        {
            _log = log;
        }

        public void Init(IRuntimeServices rs)
        {

        }

        public void LogVelocityMessage(LogLevel level, string message)
        {
            switch (level)
            {
                case LogLevel.Debug:
                    _log.Debug(message);
                    break;
                case LogLevel.Info:
                    _log.Info(message);
                    break;
                case LogLevel.Warn:
                    _log.Warn(message);
                    break;
                case LogLevel.Error:
                    _log.Error(message);
                    break;
            }
        }
    }
}

Then, when creating the engine:

var engine = new VelocityEngine();
var props = new ExtendedProperties();    
props.SetProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM,
new Log4NetILogSystem(LogManager.GetLogger(typeof(NVelocityEngine))));
engine.Init(props);
ghallas
  • 285
  • 2
  • 14