powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Логирование
25 сообщений из 55, страница 2 из 3
Логирование
    #38496930
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320,

Да. Именно так. Когда вы пишете Log.Info() - то сообщение будет выведено в лог, если в конфиге для указанного логгера стоит уровень Info и выше.
...
Рейтинг: 0 / 0
Логирование
    #38498269
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79Не претендую на правильность высказанной мысли. Просто возможно этот кусок кода наведет вас на правильные мысли:

Наследник ActionFilterAttribute
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
    /// <summary>
    /// Атрибут для логирования действий контроллеров
    /// </summary>
    public class LogAttribute: ActionFilterAttribute
    {
        public LogLevel Level { get; set; }
        public String Name { get; set; }

        public LogAttribute()
        {
            Level = LogLevel.All;
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (String.IsNullOrEmpty(Name))
                Name = String.Format("{0}.{1}", filterContext.ActionDescriptor.ControllerDescriptor.ControllerType.FullName, filterContext.ActionDescriptor.ActionName);

            var logger = LogManager.GetLogger(Name);

            if (logger is NoOpLogger)
                throw new KeyNotFoundException(String.Format("Не найден логгер для указанного источника '{0}'", Name));

            Action<FormatMessageHandler> action = handler => handler(
                "Пользователь: {0}, Источник: {1}, Метод: {2}, Аргументы: {3}", 
                filterContext.RequestContext.HttpContext.User.Identity.Name,
                filterContext.ActionDescriptor.ControllerDescriptor.ControllerType.FullName,
                filterContext.ActionDescriptor.ActionName,
                String.Join(", ", filterContext.ActionParameters.Select(kv => String.Format("{0}='{1}'", kv.Key, kv.Value))));

            switch (Level)
            {
                case LogLevel.All:
                case LogLevel.Trace:
                    logger.Trace(action);
                    break;
                case LogLevel.Debug:
                    logger.Debug(action);
                    break;
                case LogLevel.Info:
                    logger.Info(action);
                    break;
                case LogLevel.Warn:
                    logger.Warn(action);
                    break;
                case LogLevel.Error:
                    logger.Error(action);
                    break;
                case LogLevel.Fatal:
                    logger.Fatal(action);
                    break;
                case LogLevel.Off:
                    break;
                default:
                    throw new ArgumentOutOfRangeException("Неизвестный науке зверь...");
            }

            base.OnActionExecuting(filterContext);
        }
    }


Спасибо за подсказку. Но я так понимаю, что надо будет к каждому контроллеру по такому атрибуту приписывать? Хотя, наверное, можно ограничиться каким-нибудь базовым контроллером.

А что вы думаете, если в базовом контроллере переписать метод OnException и поместить весь ваш код (или его аналог - короче, код вытаскивания нужной информации и её логирования) туда? Вроде, OnException как раз для этого подходит?
...
Рейтинг: 0 / 0
Логирование
    #38498288
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И ещё. Я вот уже несколько раз встречал, что люди как-то не хотят обрабатывать ошибки через атрибуты контроллеров или секцию customErrors в веб.конфиге. Почему? Один даже пишет : "was running into all kinds of problems". Почему-то именно в Application_Error в Global.asax.cs пытаются обрабатывать ошибки.

Пока нашёл довольно подробные советы , как и что делать. Хотя, кто-то там в комментах не согласен и тоже неплохую ссылку приводит.
...
Рейтинг: 0 / 0
Логирование
    #38498517
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я не спец в ASP.NET, поэтому повторюсь, не стоит мои слова воспринимать как экспертное мнение

Тем не менее, у контроллеров есть метод OnException, через который можно получить доступ к ExceptionContext. Почему бы не определить свой контроллер с переопределенным этим методом, а все свои контроллеры наследовать от него?

PS Если сделаете, как хотите, не забудьте код выложить, я бы тоже посмотрел...
...
Рейтинг: 0 / 0
Логирование
    #38498858
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320И ещё. Я вот уже несколько раз встречал, что люди как-то не хотят обрабатывать ошибки через атрибуты контроллеров или секцию customErrors в веб.конфиге. Почему? Один даже пишет : "was running into all kinds of problems". Почему-то именно в Application_Error в Global.asax.cs пытаются обрабатывать ошибки.

Пока нашёл довольно подробные советы , как и что делать. Хотя, кто-то там в комментах не согласен и тоже неплохую ссылку приводит.
Перечитал всё. Как я понял, что кастомный атрибут, что OnException - всё одно и то же. И работают оба этих варианта в контексте контроллеров и действий. Т. е. ошибки уровня приложения (если я правильно выражаюсь) не отслеживают. Самое лучшее - это и атрибуты (или OnException) для специфических ошибок, и Application_Error - для всего остального. Но это для моего простого сайта это будет логики на четверть моего приложения. Поэтому для быстроты и простоты ограничусь тем, что всё запихну в Application_Error. Тем более, что и оттуда можно легко получить доступ к контексту текущего запроса через this.Context, или HttpContext.Current, или даже ещё варианты есть.

Вместо навороченной логики по вытаскиванию имён контроллеров и действий, решил воспользоваться простым Context.Request.Url.AbsoluteUri - сразу всё видно в одной строке, да ещё и параметры запроса видны. Правда, наверное, если это писать в БД или с помощью специальных просмотрщиков логов обрабатывать, то фильтрации по контроллерам-действиям и прочему не будет. Вобщем, подумаю над этим.
...
Рейтинг: 0 / 0
Логирование
    #38498867
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320Context.Request.Url.AbsoluteUri - сразу всё видно в одной строке, да ещё и параметры запроса видны

Да? и параметры, передаваемые через POST?
...
Рейтинг: 0 / 0
Логирование
    #38498868
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторПеречитал всё. Как я понял, что кастомный атрибут, что OnException - всё одно и то же.
Между ними отличия ровно в том же, в чём отличия между атрибутом контроллера и просто кодом в контроллере.
...
Рейтинг: 0 / 0
Логирование
    #38498892
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79user7320Context.Request.Url.AbsoluteUri - сразу всё видно в одной строке, да ещё и параметры запроса видны

Да? и параметры, передаваемые через POST?
Не пробовал. Я не умею имитировать POST-запрос. А так у меня все "посты" имеют в параметрах модель - там всякие привязки-развязки работают. При этом ненавязчивая валидация на клиенте через javascript... Как сымитировать POST с ошибкой в моём случае, чтобы вызвать исключение? Тогда я проверю, будут там параметры в AbsoluteUri или нет.

Вы там про то, что у меня получится, просили написать. Да я в этом мало разбираюсь, поэтому по-простому просто в Application_Error всё запульну и буду логировать, а юзеру выдавать заглушку "Опаньки..." или что-то в этом роде. А код буду использовать вот что по ссылкам и у вас - он одинаковый. Единственное, что от себя добавлю - это NLog настрою так, как я хотел - т. е. имя юзера, полный адрес с параметрами запроса (таким способом или другим) и трассировку стека вызова функций. Пожалуй, хватит. По мере пользования буду, наверное, добавлять всякие фильтры, чтобы не логировались всякие дурацкие вещи, типа юзер неправильно имя контроллера-действия в адресной строке набрал или не тот айдишник вбил. Это для любителей руками адреса вводить - им-то, может, и всё равно, а у меня логи мусором забиваться будут. Вобщем, сразу так я это логирование не построю - надо опыта поднабраться и по мере пользования настраивать.
...
Рейтинг: 0 / 0
Логирование
    #38498906
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторЕдинственное, что от себя добавлю - это NLog настрою так, как я хотел - т. е. имя юзера, полный адрес с параметрами запроса (таким способом или другим) и трассировку стека вызова функций.
Ещё только вот это добавлю. ))
...
Рейтинг: 0 / 0
Логирование
    #38498910
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320авторЕдинственное, что от себя добавлю - это NLog настрою так, как я хотел - т. е. имя юзера, полный адрес с параметрами запроса (таким способом или другим) и трассировку стека вызова функций.
Ещё только вот это добавлю. ))
В смысле, что проход по всем вложенным исключениям и их логирование.
...
Рейтинг: 0 / 0
Логирование
    #38499903
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79user7320Context.Request.Url.AbsoluteUri - сразу всё видно в одной строке, да ещё и параметры запроса видны

Да? и параметры, передаваемые через POST?
Так. Кинул исключение ручками на POST-запросе и посмотрел, что залогировалось.

Сразу скажу, что ваша строка

Код: c#
1.
String.Join(", ", filterContext.ActionParameters.Select(kv => String.Format("{0}='{1}'", kv.Key, kv.Value))));



для меня оказалась непонятна в том смысле, что я не понял, как в Application_Error получить объект ActionExecutingContext (у вас такого типа - параметр filterContext), чтобы вытащить параметры запроса. Но я нашёл другой способ - Request.Unvalidated.Form. Вот так можно получить все параметры формы, включая скрытые, включая всякие __RequestVerificationToken:

Код: c#
1.
2.
3.
4.
this.Context.Request.Unvalidated.Form
    .Cast<string>()
    .Select(key => new KeyValuePair<string, string>(key, ctx.Request.Unvalidated.Form[key]))
    .Select(pp => String.Format("{0}='{1}'", pp.Key, pp.Value))



Приведение Form типа NameValueCollection взял отсюда - http://stackoverflow.com/a/396504/808128 .

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

Если вы знаете, как получить ActionExecutingContext в Application_Error, то буду благодарен - чтобы не маяться с приведением формы и её разложением.
...
Рейтинг: 0 / 0
Логирование
    #38499910
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Точнее, полностью код выглядит так:

Код: c#
1.
2.
3.
4.
5.
6.
String.Join(
    "\n", 
    this.Context.Request.Unvalidated.Form
        .Cast<string>()
        .Select(key => new KeyValuePair<string, string>(key, ctx.Request.Unvalidated.Form[key]))
        .Select(pp => String.Format("{0}='{1}'", pp.Key, pp.Value)))
...
Рейтинг: 0 / 0
Логирование
    #38499918
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что интересно, перепробовал все поля и подполя в this.Context - нигде не нашёл параметров запроса, кроме как в форме. Даже this.Context.Request.RequestContext.RouteData содержит только имена контроллера и действия.
...
Рейтинг: 0 / 0
Логирование
    #38499925
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320что я не понял, как в Application_Error получить объект ActionExecutingContext
Ну так он для действий же. Изначально у меня не стояла задача ловить только ошибки. Нужно было логировать обращения к методам, и все.

user7320чтобы не маяться с приведением формы и её разложением.
Кажется, раскладкой параметров в модель занимается DefaultModelBinder. Или его наследники (созданные вами).
...
Рейтинг: 0 / 0
Логирование
    #38499942
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79user7320что я не понял, как в Application_Error получить объект ActionExecutingContext
Ну так он для действий же. Изначально у меня не стояла задача ловить только ошибки. Нужно было логировать обращения к методам, и все.

user7320чтобы не маяться с приведением формы и её разложением.
Кажется, раскладкой параметров в модель занимается DefaultModelBinder. Или его наследники (созданные вами).
Про раскладку формы я имел ввиду мой код - вот эта портянка может быть как-нибудь сокращена? Или вы тоже пока не знаете, как попроще получить параметры POST-запроса?
...
Рейтинг: 0 / 0
Логирование
    #38499946
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320Arm79пропущено...

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

пропущено...

Кажется, раскладкой параметров в модель занимается DefaultModelBinder. Или его наследники (созданные вами).
Про раскладку формы я имел ввиду мой код - вот эта портянка может быть как-нибудь сокращена? Или вы тоже пока не знаете, как попроще получить параметры POST-запроса?

Именно в Application_Error, я имею ввиду, а не в контроллерах или действиях.
...
Рейтинг: 0 / 0
Логирование
    #38499958
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320,

На память не помню, но вроде параметры формы можно получить из свойства Request.Form
...
Рейтинг: 0 / 0
Логирование
    #38500071
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79user7320,

На память не помню, но вроде параметры формы можно получить из свойства Request.Form
Ну, это то же, что и у меня, только до валидации. По идее, надо как раз брать Request.Unvalidated.Form, чем Request.Form, чтобы можно было воспроизвести исключение, т. к. это то, что юзер непосредственно ввёл.
...
Рейтинг: 0 / 0
Логирование
    #38500338
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вобщем, намалевал вот что пока:

в NLog таргет вот такой простой

Код: xml
1.
2.
3.
4.
5.
6.
<target
	name="logFile"
	xsi:type="File"
	fileName=".../siteLog.txt"
	layout="${longdate} ${newline} ${message} ${newline} ${newline}" >
</target>



В Global.asax портянка

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
protected void Application_Error()
{
    HttpContext ctx = this.Context;
    Exception lastException = Server.GetLastError();

    StringBuilder sb = new StringBuilder();

    sb.AppendLine("_User:");
    sb.AppendLine(ctx.User.Identity.Name);
    sb.AppendLine("_Absolute URI:");
    sb.AppendLine(ctx.Request.Url.AbsoluteUri);
    sb.AppendLine("_POST request unvalidated form fields:");
    sb.AppendLine(
        String.Join(
            "\n",
            ctx.Request.Unvalidated.Form
                .Cast<string>()
                .Select(key => new KeyValuePair<string, string>(key, ctx.Request.Unvalidated.Form[key]))
                .Select(pp => String.Format("{0}='{1}'", pp.Key, pp.Value))));
    sb.AppendLine("_Route data values:");
    sb.AppendLine(
        String.Join(
            "\n",
            ctx.Request.RequestContext.RouteData.Values
                .Select(p => String.Format("{0}='{1}'", p.Key, p.Value))));
    sb.AppendLine("_Stack trace:");
    sb.AppendLine(lastException.StackTrace);
    sb.AppendLine("_Exceptions info:");
    do
    {
        sb.AppendLine(lastException.Message);
        lastException = lastException.InnerException;
    }
    while (lastException != null);

    MvcApplication.Logger.Trace(sb.ToString());
}



Проверил на GET- и POST-запросах - работает. Если нет параметров формы (GET-запрос, например) - то просто пустое место.
...
Рейтинг: 0 / 0
Логирование
    #38500342
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот только думаю, что проблемы с просмотрщиками могут быть. Вроде, чтобы они там удобно показывали, надо все вот эти мои заголовки, типа "_Stack trace" и т. п. в настройки layout для NLog поместить. Вобщем, посмотрю. Главное, я получил, чего хотел.
...
Рейтинг: 0 / 0
Логирование
    #38500344
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А, вот ещё забыл показать юзеру нормальную заглушку, а не трассировку стека вываливать.
...
Рейтинг: 0 / 0
Логирование
    #38501141
SeVa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если интересует только логирование ошибок asp.net, то я бы рекомендовал elmah
...
Рейтинг: 0 / 0
Логирование
    #38501278
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SeVaЕсли интересует только логирование ошибок asp.net, то я бы рекомендовал elmah
Мне нужно все исключения логировать. Пока. Потом я будут фильтровать, какие логировать не стоит. Но, как я понял, штука в том, что на самом деле достаточно самого простого логировщика - буквально, который будет тупо аппендить тестовый файл или в БД записывать. Я имею ввиду, что сами исключения и всю необходимую инфу я собираю сам и превращаю её либо в объект, либо в строку. А от логировщика уже нужно только уметь обращаться с этим объектом или строкой - очень простое требование, правда?

Я вот тот же NLog глянул - там логирование, например, в текстовый файл не содержит в себе никакой магии - String.Append на каждом шагу, а потом просто добавляет в файл и всё. Такое и я сам мог бы написать. Единственный плюс - в предустановленных шаблонах записи (типа дат, исключений конкретного типа, назначений записей логов (файл, БД и пр.) и т. п.), которые можно настраивать в файле конфигурации - т. е. без перекомпиляции всего проекта. Т. е. сам бы я такое долго писал, а тут всё готовое. В то же время никакого ноу-хау тут нет - просто освободжают от рутины.

Короче, для меня сейчас все эти логировщики на одно лицо - умеют писать в файл или БД и всё - мне этого за глаза хватит пока.
...
Рейтинг: 0 / 0
Логирование
    #38501957
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Посмотрел примеры работы с Application_Error. Не понял, почему у всех завидное пристрастие к использованию Response.Clear() и Server.ClearError()? Вот примеры:

http://stackoverflow.com/a/1171805/808128
http://www.prideparrot.com/blog/archive/2012/5/exception_handling_in_asp_net_mvc#returningviews


Некоторые даже целую портянку пишут:

Код: c#
1.
2.
3.
4.
httpContext.ClearError();
httpContext.Response.Clear();
httpContext.Response.StatusCode = ex is HttpException ? ((HttpException)ex).GetHttpCode() : 500;
httpContext.Response.TrySkipIisCustomErrors = true;



Посмотрел в МСДН :
авторThe following example sets the ContentType property for the response to image/jpeg, calls the Clear method to remove other content that might be attached to the response, and then sets the BufferOutput property to true so that the complete page will be processed before any content is sent to the requesting client.
Т. е. я так понимаю, что если к ответу сервера уже что-то было приложено, какой-то контент, и ошибка возникла после того, как к ответу что-то было приложено, то если стоит задача только сообщить юзеру об ошибке, то нет смысла отправлять ему этот контент? Я правильно понимаю?

Теперь по Server.ClearError(). Посмотрел в МСДН и тоже не очень понял. Единственное, как я понял, на что оно может сгодиться - очистить логи сервера от логирования обработанных исключений. Т. е. раз мы его обработали, то и логировать его вроде как не нужно?
...
Рейтинг: 0 / 0
Логирование
    #38502114
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
25 сообщений из 55, страница 2 из 3
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Логирование
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]