За что Вы извиняетесь-то? :)
Вы, конечно, правы, не надо писать в windows event log миллионы сообщений, он для этого не предназначен. Для этого есть другие системы накопления логов. И разобираться с тем, что пишется в логи тоже нужно. Однако, нагрузка может быть вполне обоснованной. А потеря производительности при последовательной записи в stdout выражается не бинарным стостоянием (либо есть, либо нет), она варьируется в зависимости от нагрузки на веб сервис, и заметные потери могут проявиться уже при частичной загрузке потока. На мой взгляд, просто не надо к нему привязываться, и, не надо использовать такую вот обёртку вокруг него, которая выполняет операции ввода-вывода под мьютексом. Есть готовые библиотеки, в которых поборолись за масштабируемость и производительность. И прямые каналы записи в системы накопления логов быстрее, и, можно писать параллельно с нескольких потоков, и, не нужно сериализовать/восстанавливать данные лишний раз. Всё это можно сделать правильно, не привязываясь к конкретной среде исполнения.
они пишутся в консоль и более никуда. Это нормально для консольного приложения системного и инфраструктурного назначения. Почему это вас так напрягает? Я не ставил задачи перенаправить это в системный журнал
Да потому, что обёртка — это не консольное приложение, а windows service. А у windows services нет консоли :) Вы помните вообще, зачем Вы взялись её писать?
Хорошо, допустим, что не было замысла писать сообщения обёртки в event log. Тогда почему в режиме консольного приложения она как раз это и делает? Этот пример вообще Вы писали?
естественно для рабочего приложения времени уйдёт больше, чем на демонстрационный пример. Я вам показал что это в принципе просто решается, в контексте обсуждения этого достаточно.
Снова переобуваемся на лету. Вы сказали дословно: «Когда мне нужно запускать веб-сервис в виде службы windows, я напишу обычный веб-сервис и без проблем запущу его в виде службы и направлю stdout куда мне надо без посторонних «агентов» и докеров. Цена вопроса — ~15-20 строк банального кода.». Речь идёт здесь не о примере, а именно о продукте. Вопрос про пример появился позже.
ровно стой же скоростью, с которой строка выводится в консоль при разработке, не больше и не меньше.
Разумеется! И это ни разу не быстро. И сидит под mutex, поэтому не масштабируется вширь вообще никак. Пока один поток пишет — все остальные ждут. Это как очередь на кассу с одним кассиром в магазине. Хоть миллион человек туда запусти — если кассир выпускает одного человека в минуту, с покупками оттуда за час выйдет ровно 60 человек.
«логи самой обёртки в event log не пишутся» — я и не собирался. зачем мне это делать?
А куда они тогда пишутся? Ведь обёртка эти сообщения создаёт. Значит, замысел их выводить тоже был. Или они там для красоты? :)
А вот эта реплика — "Если не уверены, можете самостоятельно проделать простейшую гимнастику (go mod init; go run. prog.exe; см. системный журнал «my service») и убедиться, как это сделал я" очевидно, относится вот к этому моему комментарию: куда пишутся логи самой обёртки тоже не очень понятно (ок, это может быть моё незнание golang, и они на самом деле тоже пишутся в eventLog, но я в этом не уверен)
Всё это обычное переобувание на лету.
неуместные придирки. Естественно для демонстрационного примера обработка ошибок и перезапуск сервиса меня не интересуют
Я просто напомню, с чего возник интерес к примеру. Конкретно, вот с этого Вашего утверждения: Когда мне нужно запускать веб-сервис в виде службы windows, я напишу обычный веб-сервис и без проблем запущу его в виде службы и направлю stdout куда мне надо без посторонних «агентов» и докеров. Цена вопроса — ~15-20 строк банального кода. . На проверку оказалось, что чудес на свете не бывает, что написать обёртку займёт отнюдь не 15-20 строк кода, а на пару порядков больше, да и времени на отладку уйдёт заметное количество. Приврали ради красного словца. Ну что же, бывает.
По поводу того, что запись логов в конечный журнал может тормозить — естественно может, спасибо кэп.
Ну что же опускаться до подмены сказанного собеседником на то, что удобно для себя? Напомню, речь не идёт о том, как _собираются_ логи с потока. А о том, как _сам сервис_ пишет их в поток вывода. Ваше предложение: достаточно простой обёртки над выводом в stdut… К счастью, я пишу на Go, и мне не сотавляет труда поставить мьютекс там, где есть доступ к стейту, и радоваться жизни. Ваше предложение однозначно понимается как устроить бутылочное горлышко, посадив запись в поток вывода под мьютекс. Именно в Вашей обёртке и будут тормоза.
а само по себе использование служб виндовз в качестве веб сервисов — бесСмыслица и мартышкин труд.
Заметьте, не я это предложил: Когда мне нужно запускать веб-сервис в виде службы windows, я напишу обычный веб-сервис и без проблем запущу его в виде службы и направлю stdout куда мне надо без посторонних «агентов» и докеров.
Если вынусть слово«веб» из этого тезиса, опять же, ничего не изменится. Парсить stdin в windows service, вместо того, чтобы принять callback от Service Control Manager — это бессмыслица, и мартышкин труд. Как и писать логи из windows service в поток вывода, потом городить обёртку, которая их будет перекладывать в event log.
бесСмыслица (с двумя «с»)
Вы хотите поиграть в игру про правописание? Это было бы несложно:
Ни какие, ни какая — пишется слитно.
Не уместны — тоже слитно.
Ни кто — снова, слитно.
логии — пишется с одной «и»
и т.д. Но здесь, всё же, не занятия по правописанию, и, придираться к опечаткам в комментариях на Хабре — это несусветная глупость.
Если не уверены, можете самостоятельно проделать простейшую гимнастику
Раз это windows service, то пример был скомпилирован и установлен как windows service.
Баг №1 — интуиция меня не обманула. Нет, логи самой обёртки в event log не пишутся. Только обёрнутного приложения. Что интересно, если запускать с консоли, то да, логи обёртки тоже попадают в event log. Но мы же сервис тестируем.
Баг №2 — если обёртка аварийно завершает работу, обёрнутое приложение продолжает работать, все логи уходят в никуда
Баг №3 — после Бага №2, при попытке перезапустить сервис, запускается второй экземпляр оборачиваемого приложения.
Баг №4 — если обёрнутое приложение завершается, обёртка-сервис продолжает работать. Сервиса уже нет, но никто ни сном, ни духом, и у Windows шанса перезапустить сервис или поднять предупреждение нет.
Баг №5 — Если сообщение длинное, то оно в event log не пишется. Ошибок о сохранении сообщения в логе тоже не пишется. Длинные сообщения уходят в никуда.
Баг №6 нам уже известен — при остановке сервиса обёрнутое приложение аварийно завершается, со всеми вытекающими.
Про отсутствие хотя бы катерогий сообщений в обёртке я уже молчу.
Эти ошибки я нашёл за 10 минут экспериментов, и, они отнюдь не мелочи, они могут обернуться финансовыми и репутационными потерями для заказчика.
В Go мьютексы бесплатны и не блокируют поток ос, поскольку все инструкции асинхронны.
Какими бы бесплатными не были мьютексы, какими бы асинхронными не были инструкции, тот код, что защищен мьютексом, всегда выполняется только в одном экземпляре, последовательно. А под мьютексом у Вас — операция ввода-вывода, недешевая, надо сказать, операция. Очевидно, что за одну единицу времени больше запросов, чем количество раз, которое может исполниться код под мьютексом, сервис исполнить не сможет. А учитывая, что чаще всего на один запрос пишется несколько сообщений, можно смело уменьшать число запросов ещё на порядок. И решение это не масштабируется. Это обычное бутылочное горлышко — ошибка новичка.
Ну и про парсить stdin в веб-сервисе — это уже полная бесмыслица и мартышкин труд.
Приветствую усилия по написанию примера. Получилось, правда, заметно больше, чем 15-20 строк, никаких структурированных логов (да и вообще всё валится в одну кучу), и это мы его ещё не тестировали. При этом мы потеряли часть функционала Windows Service — просто, потому, что консольное приложение так не может, с безопасным завершением сервиса по команде остановки есть вопросы, куда пишутся логи самой обёртки тоже не очень понятно (ок, это может быть моё незнание golang, и они на самом деле тоже пишутся в eventLog, но я в этом не уверен). Это так, на вскидку. И всё это лишь для того, чтобы выводить логи в консоль. Не мучайтесь! Возьмите для C# Log4Net. Вы получите всё то же самое, только не нужно будет изголяться с обязательным пропусканием логов через стандартный вывод.
Не можете разработать код, который пишет в консоль, и полагаете, что другие не могут?
Как Вы там выше писали? — «Это _вы_ не можете, говорите за себя.» :) Перенаправить логи в стандартный вывод дело нехитрое, только бесмыссленное, при наличии более эффективных и надёжных способов.
Я пишу всё в консоль и в принципе не задумываюсь о реализации логгирования.
Это иллюзия, ибо заказчику нужно полное работающее решение, а не бинарник, пишуший в консоль. Поэтому вот то, что Вы написали в примере — будет частью Вашей работы, и Вам придётся этот код писать, тестировать, и поддерживать.
Вы воюете с мельницей, поскольку такой подход к логгированию используется чуть более чем везде.
Это просто смешно. Конечно же нет, он не используется везде. В области Вашей практики — возможно, но это не весь мир, и это не значит, что этот подход верный.
Да, именно так у меня и есть. Благодаря следованию принципам 12f мои приложения не содержат плотформенных зависимостей, связанных с логгированием.
Принцип 12f имеет к этому весьма опосредованное отношение, интерфейсы не его авторы изобрели. Скажем так, он предлагает делать это через выхлопную трубу.
На C# нельзя просто залочить мьютексом shared mutable state и одидать что это заработает.
Мьютекс на каждую запись в логи в продакшн сервисе? Это Вы серьёзно, да? Ну и про С# конечно тоже повеселило, спасибо.
Но вы опять не разобрались в вопросе. Azure умеет в докер, следовательно полностью соответсвует 12f в части логгирования.
Как Вы там писали? — А! «Это _вы_ не разобрались, говорите за себя.». Azure это делеко не только Docker, и, к счастью, не страдает параноидальным желанием засунуть всё в стандартный вывод, за что ему и спасибо.
А давайте тогда я буду говорить «консоль», а вы не будете меня одёргивать.
Давайте Вы будете называть поток вывода как Вам удобно, и не будете мне затыкать рот, когда я высказываю по этому поводу своё мнение?
При разработке я думаю не о том, как логгировать, а о том, что логгировать.
Это, очевидно, не так. Вы думаете исключительно о том, _как_ логгировать в поток вывода, и, именно поэтому Вам приходится изобретать способ обернуть своё консольное приложение так, чтобы оно выглядело как Windows service, наплевав при этом на производительность, отказоустойчивость, простоту обслуживания. И Вы прекрасно иллюстрируете, почему постулирование записи в поток вывода — это ошибка.
Зона ответственности приложения заканчивается на вызове методов ILogger.Log*whatever*. Что происходит с логами дальше — это уже не забота разработчика.
При этом мне для логгирования наплевать, в каком окружении работает мой сервис, в amazon cloude или в виде службы windows — мне не нужно менять программу, чтобы адаптировать её под произвольный журнал.
Запись логов в поток вывода не является необходимым условием для этого. Более того, Вам не наплевать — Вам приходится выкручиваться, чтобы приспособить среду выполнения к бесмысленному требованию.
Зачем? Это элементарные вещи.
Хорошо, всё понятно. Вы — не можете.
погуглил за вас
Спасибо, ссылка не имеет абсолютно никакого отношения к вопросу, и примера у Вас нет. Кстати, Вы заметили, как ловко автор заметает под ковёр вопрос конвертации даты? :)
То есть любой конкурентный код у вас по определению не может быть простым? Ну пусть будет так — простой для меня и сложной для вас обёртки.
Безусловно, правильная реализация многопоточности — это уже непростой код, а шапкозакидательство не свидетельство квалификации. Обычно, наоборот.
Не знаю… Вообще по отзывам админов/девопсов azure cloud — проприетарщина и отвратительное соотношение цена/качество, и не понятно кто его использует и зачем
Это второй пример дискредитации фактов, которые не укладываются в стройную теорию манифеста. Ну и не надо тогда претендовать на всеобъемлющесть, и пропихивать guidelines для частного случая везде, где только можно.
Это вообще не имеет значения. Называйте как хотите. Не надо навязывать другим своё мнение.
Это публичный форум, я высказываю свое мнение, и имею на это право. Вы имеете полное право с ним не соглашаться, поэтому ни о каком навязывании речи не идёт.
Очевидно это не верно
Это, очевидно, верно, и, именно поэтому потребовалось втащить в дискуссию Docker. И Вы же с этим согласны: «Какая ниша — такая и инфраструктура, такой и уровень соответствия современным рекомендациям».
Вопрос целесообразности я не поднимал, не надо всё мешать в одну кучу. И понимаете вы его не правильно если что.
Спасибо за диагноз, так сказать, по фотографии, давайте Вы уж тогда поясните критерии целесообразности вот этого: «Запускать бинарник из процесса, который стартует службу и выполняет в ней бинарник, при этом перехватывает stdout бинарника и пишет его в системный журнал», и вот этого в контексте Windows service: Элементарно создаётся на пальцах. Докер. nssm.cc .
Когда мне нужно запускать веб-сервис в виде службы windows, я напишу обычный веб-сервис и без проблем запущу его в виде службы и направлю stdout куда мне надо без посторонних «агентов» и докеров. Цена вопроса — ~15-20 строк банального кода.
Научиться чему-то новому — всегда полезно, серьёзно. Если это можно сделать в 15-20 строк кода — с интересном изучу. Опубликуете?
Любые. Прочитайте об общих понятиях структурного логгирования прежде чем задавать подобные вопросы.
Это уход от ответа. Если Вы разбираетесь в этом хорошо, совершенно несложно привести конкретный пример.
Потому что они относятся к логгированию и ни к чему более. Но опять таки ни кто вам не мешает предавать ключ-значение напрямую, без ILogger, или вообще не использовать коль вы не умеете в структурное логгирование.
Давайте перейдём от диагнозов по фотографии к конкретным примерам.
Кстати, логгер у нас уже хранит состояние, плюс поддерживает многопоточную запись. Уже есть сомнения в возможности " достаточно простой обёртки над выводом в stdut"
Ну и напоследок добавлю: да, Windows services это очень старая инфраструктура. Ну а Azure Application Services, Azure Functions, etc.? Тоже объявим дремучими и маргинальными?
Это ни какая не грубая ошибка, а нормальное отождествление наиболее распространённого случая. По умолчанию stdout для разработчика — это консоль практически всегда.
Если разработчик оговорился — это ещё можно понять, но если такое отождествление нормально, это явные проблемы в понимании архитектуры.
Элементарно создаётся на пальцах. Докер. nssm.cc Наверняка есть и что-то ещё, просто вы не в курсе
Да, конечно, давайте посадим Windows service в докер-контейнер, со всеми его накладными расходами, и побъёмся над тем, чтобы обеспечить нужное поведение. Есть такая штука — целесообразность применения — наверное, Вы просто не в курсе.
А теперь давайте взглянем с точки зрения манифеста 12. Среда исполнения Windows service — это таки Windows, со своим, особым взаимодействием с сервисами. То, что Вы предлагаете — это вкрутить ещё одну прослойку между сервисом и средой исполнения так, чтобы приложение можно было уложить в прокрустово ложе манифеста. Ну будет у Вас Docker этим самым агентом. Всё равно ничего не изменится.
Нет. Логгер нужно передавать в каждую функцию/метод в качестве параметра, чтобы получить в сообщении предопределённый сверху стека вызовов набор ключ-значение
Я так понимаю, это желание выдать частное, и спорное архитектурное решение за общий случай? Какие, простите, ключи и значения необходимо передавать в каждый метод в стеке, и почему их обязательно необходимо оборачивать в логгер?
Нет, консоль — это не stdout. Хотя, действительно, чаще всего stdout перенаправляется на консоль, отождествлять их — это грубая ошибка. Консоль это инфраструктура, включающая в себя экранный буфер, c произвольным доступом, аттрибутами символов и буфер ввода, имеющие свой собственный API. Для приложения выводить на консоль и выводить в stdout — это две большие разницы.
По поводу «простой обёртки над выводом» — с фактом наличия этой обёртки мы уже определились. Если возражений о том, что у этой обёртки есть набор публичных методов aka API, нет, то у нас получается тот самый логгер, только, скажем, не FileLogger, а StdoutLogger. А дальше, до введения собственно интерфейса ILogger остаётся один шаг.
Почему нужен агент? — в реальности, среда выполнения и инфраструктура журналирования не тождественны, а в случае с Windows service, приведённом выше, такая инфраструктура журналирования, как описывается в манифесте 12 factor app, просто отсутствует. Вот мы и получаем, с одной стороны — ILogger, с другой — необходимость в промежуточном агенте. Контейнер зависимостей, динамично выстраеваемый под конкретную среду выполнения, хотя и не без серьёзных недостатков, имеет право на существование, как решение этой потребности. Правда, лично мне для .Net больше нравится Apache Log4Net.
В 12 factor apps речь идёт не о консоли, конечно. Постулируется, что «Приложение двенадцати факторов никогда не занимается маршрутизацией и хранением своего потока вывода… Вместо этого каждый выполняющийся процесс записывает свой поток событий без буферизации в стандартный вывод stdout.»
Если с первой частью я согласен, в пределах её применимости, то вторая, на мой взгляд, ошибочна. В более-менее серьёзном (веб-) сервисе логи структурированные. Помимо текстового сообщения, каждая запись несет в себе дополнительные данные и метаданные. Простым выводом в stdout тут не отделаешься. Нужен промежуточный агент со своим интерфейсом, позволяющий приложению записать структурированное событие и передающий его среде исполнения.
Со всем уважением к вашему проекту, но почему всё же "первые", если уже есть, например, WorkOutDoors?
Вы, конечно, правы, не надо писать в windows event log миллионы сообщений, он для этого не предназначен. Для этого есть другие системы накопления логов. И разобираться с тем, что пишется в логи тоже нужно. Однако, нагрузка может быть вполне обоснованной. А потеря производительности при последовательной записи в stdout выражается не бинарным стостоянием (либо есть, либо нет), она варьируется в зависимости от нагрузки на веб сервис, и заметные потери могут проявиться уже при частичной загрузке потока. На мой взгляд, просто не надо к нему привязываться, и, не надо использовать такую вот обёртку вокруг него, которая выполняет операции ввода-вывода под мьютексом. Есть готовые библиотеки, в которых поборолись за масштабируемость и производительность. И прямые каналы записи в системы накопления логов быстрее, и, можно писать параллельно с нескольких потоков, и, не нужно сериализовать/восстанавливать данные лишний раз. Всё это можно сделать правильно, не привязываясь к конкретной среде исполнения.
Да потому, что обёртка — это не консольное приложение, а windows service. А у windows services нет консоли :) Вы помните вообще, зачем Вы взялись её писать?
Хорошо, допустим, что не было замысла писать сообщения обёртки в event log. Тогда почему в режиме консольного приложения она как раз это и делает? Этот пример вообще Вы писали?
Снова переобуваемся на лету. Вы сказали дословно: «Когда мне нужно запускать веб-сервис в виде службы windows, я напишу обычный веб-сервис и без проблем запущу его в виде службы и направлю stdout куда мне надо без посторонних «агентов» и докеров. Цена вопроса — ~15-20 строк банального кода.». Речь идёт здесь не о примере, а именно о продукте. Вопрос про пример появился позже.
Разумеется! И это ни разу не быстро. И сидит под mutex, поэтому не масштабируется вширь вообще никак. Пока один поток пишет — все остальные ждут. Это как очередь на кассу с одним кассиром в магазине. Хоть миллион человек туда запусти — если кассир выпускает одного человека в минуту, с покупками оттуда за час выйдет ровно 60 человек.
А куда они тогда пишутся? Ведь обёртка эти сообщения создаёт. Значит, замысел их выводить тоже был. Или они там для красоты? :)
А вот эта реплика — "Если не уверены, можете самостоятельно проделать простейшую гимнастику (go mod init; go run. prog.exe; см. системный журнал «my service») и убедиться, как это сделал я" очевидно, относится вот к этому моему комментарию: куда пишутся логи самой обёртки тоже не очень понятно (ок, это может быть моё незнание golang, и они на самом деле тоже пишутся в eventLog, но я в этом не уверен)
Всё это обычное переобувание на лету.
Я просто напомню, с чего возник интерес к примеру. Конкретно, вот с этого Вашего утверждения: Когда мне нужно запускать веб-сервис в виде службы windows, я напишу обычный веб-сервис и без проблем запущу его в виде службы и направлю stdout куда мне надо без посторонних «агентов» и докеров. Цена вопроса — ~15-20 строк банального кода. . На проверку оказалось, что чудес на свете не бывает, что написать обёртку займёт отнюдь не 15-20 строк кода, а на пару порядков больше, да и времени на отладку уйдёт заметное количество. Приврали ради красного словца. Ну что же, бывает.
Ну что же опускаться до подмены сказанного собеседником на то, что удобно для себя? Напомню, речь не идёт о том, как _собираются_ логи с потока. А о том, как _сам сервис_ пишет их в поток вывода. Ваше предложение: достаточно простой обёртки над выводом в stdut… К счастью, я пишу на Go, и мне не сотавляет труда поставить мьютекс там, где есть доступ к стейту, и радоваться жизни. Ваше предложение однозначно понимается как устроить бутылочное горлышко, посадив запись в поток вывода под мьютекс. Именно в Вашей обёртке и будут тормоза.
Заметьте, не я это предложил: Когда мне нужно запускать веб-сервис в виде службы windows, я напишу обычный веб-сервис и без проблем запущу его в виде службы и направлю stdout куда мне надо без посторонних «агентов» и докеров.
Если вынусть слово«веб» из этого тезиса, опять же, ничего не изменится. Парсить stdin в windows service, вместо того, чтобы принять callback от Service Control Manager — это бессмыслица, и мартышкин труд. Как и писать логи из windows service в поток вывода, потом городить обёртку, которая их будет перекладывать в event log.
Вы хотите поиграть в игру про правописание? Это было бы несложно:
Ни какие, ни какая — пишется слитно.
Не уместны — тоже слитно.
Ни кто — снова, слитно.
логии — пишется с одной «и»
и т.д. Но здесь, всё же, не занятия по правописанию, и, придираться к опечаткам в комментариях на Хабре — это несусветная глупость.
Раз это windows service, то пример был скомпилирован и установлен как windows service.
Баг №1 — интуиция меня не обманула. Нет, логи самой обёртки в event log не пишутся. Только обёрнутного приложения. Что интересно, если запускать с консоли, то да, логи обёртки тоже попадают в event log. Но мы же сервис тестируем.
Баг №2 — если обёртка аварийно завершает работу, обёрнутое приложение продолжает работать, все логи уходят в никуда
Баг №3 — после Бага №2, при попытке перезапустить сервис, запускается второй экземпляр оборачиваемого приложения.
Баг №4 — если обёрнутое приложение завершается, обёртка-сервис продолжает работать. Сервиса уже нет, но никто ни сном, ни духом, и у Windows шанса перезапустить сервис или поднять предупреждение нет.
Баг №5 — Если сообщение длинное, то оно в event log не пишется. Ошибок о сохранении сообщения в логе тоже не пишется. Длинные сообщения уходят в никуда.
Баг №6 нам уже известен — при остановке сервиса обёрнутое приложение аварийно завершается, со всеми вытекающими.
Про отсутствие хотя бы катерогий сообщений в обёртке я уже молчу.
Эти ошибки я нашёл за 10 минут экспериментов, и, они отнюдь не мелочи, они могут обернуться финансовыми и репутационными потерями для заказчика.
Какими бы бесплатными не были мьютексы, какими бы асинхронными не были инструкции, тот код, что защищен мьютексом, всегда выполняется только в одном экземпляре, последовательно. А под мьютексом у Вас — операция ввода-вывода, недешевая, надо сказать, операция. Очевидно, что за одну единицу времени больше запросов, чем количество раз, которое может исполниться код под мьютексом, сервис исполнить не сможет. А учитывая, что чаще всего на один запрос пишется несколько сообщений, можно смело уменьшать число запросов ещё на порядок. И решение это не масштабируется. Это обычное бутылочное горлышко — ошибка новичка.
Ну и про парсить stdin в веб-сервисе — это уже полная бесмыслица и мартышкин труд.
Приветствую усилия по написанию примера. Получилось, правда, заметно больше, чем 15-20 строк, никаких структурированных логов (да и вообще всё валится в одну кучу), и это мы его ещё не тестировали. При этом мы потеряли часть функционала Windows Service — просто, потому, что консольное приложение так не может, с безопасным завершением сервиса по команде остановки есть вопросы, куда пишутся логи самой обёртки тоже не очень понятно (ок, это может быть моё незнание golang, и они на самом деле тоже пишутся в eventLog, но я в этом не уверен). Это так, на вскидку. И всё это лишь для того, чтобы выводить логи в консоль. Не мучайтесь! Возьмите для C# Log4Net. Вы получите всё то же самое, только не нужно будет изголяться с обязательным пропусканием логов через стандартный вывод.
Как Вы там выше писали? — «Это _вы_ не можете, говорите за себя.» :) Перенаправить логи в стандартный вывод дело нехитрое, только бесмыссленное, при наличии более эффективных и надёжных способов.
Это иллюзия, ибо заказчику нужно полное работающее решение, а не бинарник, пишуший в консоль. Поэтому вот то, что Вы написали в примере — будет частью Вашей работы, и Вам придётся этот код писать, тестировать, и поддерживать.
Это просто смешно. Конечно же нет, он не используется везде. В области Вашей практики — возможно, но это не весь мир, и это не значит, что этот подход верный.
Принцип 12f имеет к этому весьма опосредованное отношение, интерфейсы не его авторы изобрели. Скажем так, он предлагает делать это через выхлопную трубу.
Мьютекс на каждую запись в логи в продакшн сервисе? Это Вы серьёзно, да? Ну и про С# конечно тоже повеселило, спасибо.
Как Вы там писали? — А! «Это _вы_ не разобрались, говорите за себя.». Azure это делеко не только Docker, и, к счастью, не страдает параноидальным желанием засунуть всё в стандартный вывод, за что ему и спасибо.
Давайте Вы будете называть поток вывода как Вам удобно, и не будете мне затыкать рот, когда я высказываю по этому поводу своё мнение?
Это, очевидно, не так. Вы думаете исключительно о том, _как_ логгировать в поток вывода, и, именно поэтому Вам приходится изобретать способ обернуть своё консольное приложение так, чтобы оно выглядело как Windows service, наплевав при этом на производительность, отказоустойчивость, простоту обслуживания. И Вы прекрасно иллюстрируете, почему постулирование записи в поток вывода — это ошибка.
Зона ответственности приложения заканчивается на вызове методов ILogger.Log*whatever*. Что происходит с логами дальше — это уже не забота разработчика.
Запись логов в поток вывода не является необходимым условием для этого. Более того, Вам не наплевать — Вам приходится выкручиваться, чтобы приспособить среду выполнения к бесмысленному требованию.
Хорошо, всё понятно. Вы — не можете.
Спасибо, ссылка не имеет абсолютно никакого отношения к вопросу, и примера у Вас нет. Кстати, Вы заметили, как ловко автор заметает под ковёр вопрос конвертации даты? :)
Безусловно, правильная реализация многопоточности — это уже непростой код, а шапкозакидательство не свидетельство квалификации. Обычно, наоборот.
Это второй пример дискредитации фактов, которые не укладываются в стройную теорию манифеста. Ну и не надо тогда претендовать на всеобъемлющесть, и пропихивать guidelines для частного случая везде, где только можно.
Это публичный форум, я высказываю свое мнение, и имею на это право. Вы имеете полное право с ним не соглашаться, поэтому ни о каком навязывании речи не идёт.
Это, очевидно, верно, и, именно поэтому потребовалось втащить в дискуссию Docker. И Вы же с этим согласны: «Какая ниша — такая и инфраструктура, такой и уровень соответствия современным рекомендациям».
Спасибо за диагноз, так сказать, по фотографии, давайте Вы уж тогда поясните критерии целесообразности вот этого: «Запускать бинарник из процесса, который стартует службу и выполняет в ней бинарник, при этом перехватывает stdout бинарника и пишет его в системный журнал», и вот этого в контексте Windows service: Элементарно создаётся на пальцах. Докер. nssm.cc .
Научиться чему-то новому — всегда полезно, серьёзно. Если это можно сделать в 15-20 строк кода — с интересном изучу. Опубликуете?
Это уход от ответа. Если Вы разбираетесь в этом хорошо, совершенно несложно привести конкретный пример.
Давайте перейдём от диагнозов по фотографии к конкретным примерам.
Кстати, логгер у нас уже хранит состояние, плюс поддерживает многопоточную запись. Уже есть сомнения в возможности " достаточно простой обёртки над выводом в stdut"
Ну и напоследок добавлю: да, Windows services это очень старая инфраструктура. Ну а Azure Application Services, Azure Functions, etc.? Тоже объявим дремучими и маргинальными?
Если разработчик оговорился — это ещё можно понять, но если такое отождествление нормально, это явные проблемы в понимании архитектуры.
Да, конечно, давайте посадим Windows service в докер-контейнер, со всеми его накладными расходами, и побъёмся над тем, чтобы обеспечить нужное поведение. Есть такая штука — целесообразность применения — наверное, Вы просто не в курсе.
А теперь давайте взглянем с точки зрения манифеста 12. Среда исполнения Windows service — это таки Windows, со своим, особым взаимодействием с сервисами. То, что Вы предлагаете — это вкрутить ещё одну прослойку между сервисом и средой исполнения так, чтобы приложение можно было уложить в прокрустово ложе манифеста. Ну будет у Вас Docker этим самым агентом. Всё равно ничего не изменится.
Я так понимаю, это желание выдать частное, и спорное архитектурное решение за общий случай? Какие, простите, ключи и значения необходимо передавать в каждый метод в стеке, и почему их обязательно необходимо оборачивать в логгер?
По поводу «простой обёртки над выводом» — с фактом наличия этой обёртки мы уже определились. Если возражений о том, что у этой обёртки есть набор публичных методов aka API, нет, то у нас получается тот самый логгер, только, скажем, не FileLogger, а StdoutLogger. А дальше, до введения собственно интерфейса ILogger остаётся один шаг.
Почему нужен агент? — в реальности, среда выполнения и инфраструктура журналирования не тождественны, а в случае с Windows service, приведённом выше, такая инфраструктура журналирования, как описывается в манифесте 12 factor app, просто отсутствует. Вот мы и получаем, с одной стороны — ILogger, с другой — необходимость в промежуточном агенте. Контейнер зависимостей, динамично выстраеваемый под конкретную среду выполнения, хотя и не без серьёзных недостатков, имеет право на существование, как решение этой потребности. Правда, лично мне для .Net больше нравится Apache Log4Net.
Если с первой частью я согласен, в пределах её применимости, то вторая, на мой взгляд, ошибочна. В более-менее серьёзном (веб-) сервисе логи структурированные. Помимо текстового сообщения, каждая запись несет в себе дополнительные данные и метаданные. Простым выводом в stdout тут не отделаешься. Нужен промежуточный агент со своим интерфейсом, позволяющий приложению записать структурированное событие и передающий его среде исполнения.