Многопользовательское ведение журнала в приложении ASP.NET MVC

У меня есть мультитенантное приложение в ASP.NET MVC 5, которое может принимать входы клиентов из нескольких компаний. В настоящее время я использую log4net для входа в файлы, но он помещает все журналы всех компаний в один файл. В идеале я хотел бы разделить файлы журналов, чтобы журналы для каждой компании находились в отдельной папке.

Из этот вопрос я могу создать программный дополнительные приложения, которые затем могут регистрироваться в разных файлах журнала. Но это означало бы, что для каждого экземпляра класса мне пришлось бы продолжать вызывать

ILog log = LogManager.GetLogger("CompanyA");

чтобы получить правильный регистратор, не так ли? Есть ли лучший способ сделать это? Я также открыт для использования другого регистратора, если это будет необходимо.

Спасибо.


person Ionian316    schedule 19.05.2014    source источник


Ответы (1)


Вы используете контейнер Ioc в своем приложении? Мне удалось решить аналогичную проблему с помощью AutoFac MultitenantContainer. Шаги, которым нужно следовать

  1. определите стратегию, которую вы будете использовать для идентификации каждого арендатора.
  2. Зарегистрируйте общий интерфейс логгера в контейнере Autofac
  3. Для каждого арендатора регистрируется отдельный регистратор.

ваш код может выглядеть так (отрывок из Autofac wiki)

    var tenantIdStrategy = new RequestParameterTenantIdentificationStrategy("tenant");
    var builder = new ContainerBuilder();
    builder.RegisterType<BaseDependency>().As<IDependency>();

    // If you have tenant-specific controllers in the same assembly as the
    // application, you should register controllers individually.
    builder.RegisterType<HomeController>();

    // Create the multitenant container and the tenant overrides.
    var mtc = new MultitenantContainer(tenantIdStrategy, builder.Build());
    mtc.ConfigureTenant("CompanyA",
       b =>
        {
          b.RegisterType<Tenant1Dependency>().As<IDependency>().InstancePerDependency();
          b.RegisterType<Tenant1Controller>().As<HomeController>();
        });

Если это единственный случай, когда вам нужно различать арендаторов и на этом этапе не требуется Ioc, вы можете создать фабрику, например

static class LogFactory
{
    public static ILog GetLogger()
    {
        var requestUri = HttpContext.Current.Request.Url.AbsoluteUri;
        switch (requestUri)
        {
            case "companyA.domain.com":
                return LogManager.GetLogger("CompanyA");
            case "companyB.domain.com":
                return LogManager.GetLogger("CompanyB");
            default:
                return LogManager.GetLogger("default");
        }
    }
}

теперь используйте фабрику вместо прямого использования Logmanager

 ILog logger = LogFactory.GetLogger();
person Kamalakar Nellipudi    schedule 19.05.2014
comment
Нет, я сейчас не использую контейнер IoC. Я изучу AutoFac в будущем. Есть ли способ вести журнал без него? - person Ionian316; 20.05.2014
comment
Я мог бы подумать об использовании фабрики, которая вернет регистратор. Внутри фабрики есть логика, которая будет возвращать регистратор на основе URL-адреса запроса, если вы указали URL-адрес для каждого клиента. Когда я начинал с мутитенантным приложением, у меня было несколько требований к конкретному поведению на каждого арендатора, которые со временем только росли. Если вы хотите реализовать это как нефункциональное требование, а не только для ведения журнала, я бы посоветовал взглянуть на Autofac. - person Kamalakar Nellipudi; 21.05.2014
comment
Вау, это очень круто. Я использую Unity, и сделать что-то для каждого арендатора не так-то просто. - person Casey; 05.08.2014