3
votes

I'm using Sitecore 6.5. There is a multi-language configuration. I use items with aliases.

Aliases can be created on a content item. Click on the item > Presentation > Aliases. Enter for example: /page/stackoverflow/myitem. Click OK.

The alias is created in the content tree now, see: /sitecore/system/Aliases/*

The alias is stored in the content tree as:

- page
-- stackoverflow
--- myitem

Each item is a part of the alias created.

Problem.

The invalid urls (based on the created alias) cause errors in the errorlog. 51161 12:01:26 ERROR An alias for "/page" exists, but points to a non-existing item.

I want to change the:

  1. Log level to INFO/WARN or
  2. Log this error in a seperate errorlog or
  3. Create a custom httpRequest pipeline to avoid this error.

The above list is on the preferred order. Unless there are better possibilities to solve this problem. Is there anyone who have experienced this problem and have a good solution?

Thanks a lot.

Jordy

2

2 Answers

4
votes

Maras is spot on, but you should be able to achieve this without the HttpProcessor, by "just" fiddling a bit with the log4net settings in web.config. I unfortunately don't have the time to fully test this answer for you, but I will point you in the direction I think you should be looking.

Find the <log4net> section in web.config. It defines a series of "appenders" that each are responsible for creating different logfiles in your Sitecore solution. They look like this:

<appender name="LogFileAppender" type="log4net.Appender.SitecoreLogFileAppender, Sitecore.Logging">
  <file value="$(dataFolder)/logs/log.{date}.txt" />
  <appendToFile value="true" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%4t %d{ABSOLUTE} %-5p %m%n" />
  </layout>
</appender>

You can create your own appender; e.g. "AliasLogFileAppender" and have it logging it's content to something like <file value="$(dataFolder)/logs/Aliaslog.{date}.txt" />.

Once that is defined, all you need to do is wire it up to the namespace of Sitecore's own Alias Resolver in the httpRequestPipeline. Look just below the appenders, for the <logger> definitions. They look like this:

<logger name="Sitecore.Diagnostics.WebDAV" additivity="false">
  <level value="INFO" />
  <appender-ref ref="WebDAVLogFileAppender" />
</logger>

The "name" attribute actually denotes the namespace, that will trigger the logger.

So your configuration should look something like:

<logger name="Sitecore.Pipelines.HttpRequest.AliasResolver" additivity="false">
  <level value="INFO" />
  <appender-ref ref="AliasLogFileAppender" />
</logger>

Again, apologies for not being able to test this prior to posting. I don't see why it wouldn't work however.

I do believe there is a way in log4net to re-map a certain error message from WARN to INFO as well. Details escape me at this minute however.

2
votes

If you want to change to log level (which is the most preferable option) you need to create your own AliasResolver class using the original AliasResolver code from Sitecore, change the logging level and register it in the Sitecore config instead of original AliasResolver:

<httpRequestBegin>
  ...
  <processor type="My.Assembly.Namespace.AliasResolver, My.Assembly" />
  ...
</httpRequestBegin>
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;

namespace My.Assembly.Namespace
{
  public class AliasResolver : HttpRequestProcessor
  {
    public override void Process(HttpRequestArgs args)
    {
      Assert.ArgumentNotNull((object) args, "args");
      if (!Settings.AliasesActive)
      {
        Tracer.Warning((object) "Aliases are not active.");
      }
      else
      {
        Database database = Context.Database;
        if (database == null)
        {
          Tracer.Warning((object) "There is no context database in AliasResover.");
        }
        else
        {
          Profiler.StartOperation("Resolve alias.");
          if (database.Aliases.Exists(args.LocalPath) && !this.ProcessItem(args))
            this.ProcessExternalUrl(args);
          Profiler.EndOperation();
        }
      }
    }

    private void ProcessExternalUrl(HttpRequestArgs args)
    {
      string targetUrl = Context.Database.Aliases.GetTargetUrl(args.LocalPath);
      if (targetUrl.Length <= 0)
        return;
      this.ProcessExternalUrl(targetUrl);
    }

    private void ProcessExternalUrl(string path)
    {
      if (Context.Page.FilePath.Length > 0)
        return;
      Context.Page.FilePath = path;
    }

    private bool ProcessItem(HttpRequestArgs args)
    {
      ID targetId = Context.Database.Aliases.GetTargetID(args.LocalPath);
      if (!targetId.IsNull)
      {
        Item target = args.GetItem(targetId);
        if (target != null)
          this.ProcessItem(args, target);
        return true;
      }
      else
      {
        Tracer.Info((object) ("An alias for \"" + args.LocalPath + "\" exists, but points to a non-existing item."));
        return false;
      }
    }

    private void ProcessItem(HttpRequestArgs args, Item target)
    {
      if (Context.Item != null)
        return;
      Context.Item = target;
      Tracer.Info((object) ("Using alias for \"" + (object) args.LocalPath + "\" which points to \"" + (string) (object) target.ID + "\""));
    }
  }
}