Как стать автором
Обновить
@pawlo16read⁠-⁠only

Пользователь

Отправить сообщение
Для решения новых задач мы можем переопределить некоторые шаблоны
— всё, что у вас там написано далее в этой главе, прямо скажем — ошарашивает. Абсолютно непонятно ни каким образом решение «этих задач» связано с кастомными шаблонами, ни как вы их решили в итоге. Вот этот код, который вы привели после «Опишем шаблон функции и заглушки», он наверное очень простой и его теоретически легко понять. Но выглядит он ужасно, и ни какого желания в нём разбираться нет. Дело в том, что я уже достаточно давно в go-swagger-е, но для решения «этих задач» никогда не пользовался такой сомнительной с моей т.з. фичей, как кастомные шаблоны.

Спасибо за ответ, всё по делу. по сути оповещения пользователя ту же задачу решают — обновление данных приложения. Отложенные или рилтайм — это уже вопрос реализации протокола и инфраструктуры. Я подобную систему делал на го, не могу сказать что это было мега дорого и проблематично, но конечно от задачи зависит. По поводу хттп соединений — современные фронтенд приложения их много открывают и ни разу на них не экономят. Мне трудно оценить стоимость хттп коннекта в единицах времени работы аккумуляторной батареи, но по опыту разработки мобильного натив софта не заметил влияния. Если покажете бенчмарки, буду признателен.

Простите за банальный вопрос, но почему не вебсокеты или sse?
Самый быстрый из компактных форматов сериализации — FlatBuffers
image
Но вообще в принципе обсуждать форматы сериализации — это всё равно, что взвешивать коня в вакууме. Гораздо интереснее обсудить фреймворки, которые их используют. Apache thrift например — это rpc фреймворк если что, а не просто формат сериализации. protocol buffers — аналогично ни кому не нужен вне grpc
«А куда они тогда пишутся? Ведь обёртка эти сообщения создаёт. Значит, замысел их выводить тоже был» — они пишутся в консоль и более никуда. Это нормально для консольного приложения системного и инфраструктурного назначения. Почему это вас так напрягает? Я не ставил задачи перенаправить это в системный журнал

«15-20 строк кода, а на пару порядков больше, да и времени на отладку уйдёт заметное количество» — естественно для рабочего приложения времени уйдёт больше, чем на демонстрационный пример. Я вам показал что это в принципе просто решается, в контексте обсуждения этого достаточно.

«речь не идёт о том, как _собираются_ логи с потока. А о том, как _сам сервис_ пишет их в поток вывода» — ровно стой же скоростью, с которой строка выводится в консоль при разработке, не больше и не меньше.
«логи самой обёртки в event log не пишутся» — я и не собирался. зачем мне это делать? задача стояла перенаправить лог дочернего процесса а не основного

2 — да, я забыл вставить инструкцию, закрывающую запущенный сервис при выходе из main

3,4,6 — неуместные придирки. Естественно для демонстрационного примера обработка ошибок и перезапуск сервиса меня не интересуют

5 — ничего страшного и тоже в данном случае не важно.

Да, для продакшена я бы написал интеграционные тесты, проверяющие запуск, перезапуск, остановку, запись в сист. журнал и проч. — и что?

По поводу того, что запись логов в конечный журнал может тормозить — естественно может, спасибо кэп. По этому маршрутизаторы журналов, такие как promtail, Logplex, Fluent и logstash, кешируют и буферизирут свой ввод. И на приложении, из которого маршрутизатор получает ввод, эти тормоза -внезапно! — ни коим образом не отражаются. Ошибка новичка в данном случае — это святая уверенность в том, что если новичок не может что-то сделать быстро и просто, то это в принципе не было реализовано до него

«Ну и про парсить stdin в веб-сервисе — это уже полная бесмыслица и мартышкин труд.»

а само по себе использование служб виндовз в качестве веб сервисов — бесСмыслица (с двумя «с») и мартышкин труд.
Во-1, «стейт-машина» — это по определению не задача, а абстрактная модель. Про саму задачу вы ни слова не сказали.

Во-2, не знаю чему учили вас про конечный автомат, меня же — что его можно описать в виде графа переходов, из которого может быть получена таблица переходов. А именно — в виде размеченного ориентированного графа плюс начальное состояние. Для визуального проектирования графа и создания по нему списков смежности для любого ЯП существует огромное количество качественного и проверенного временем софта. Например, Graphviz. Вам бы стоило про это хотя бы в википедии почитать прежде чем демонстрировать наивный драндулет.

В-3, имхо в вузах лучше всё таки на теорграф делать упор. А все эти ваши авлония-уи изучать на реальных проектах, решая конкретную задачу бизнеса, а не на коне в вакууме
Усилий не потребовалось, всё тривиально. Для безопасного завершения процесса потребуется доп. протокол через stdin дочернего процесса например, поскольку windows не умеет в сигналы unix. Если не уверены, можете самостоятельно проделать простейшую гимнастику (go mod init; go run. prog.exe; см. системный журнал «my service») и убедиться, как это сделал я. Или смотреть код библиотек, например, этой — там всего лишь вызовы windows api

Структурное логгирование не имеет ни какого отношения к перенаправлению stdout. Оно реализуется библиотекой логгирования. В процессе разработки это просто вывод в консоль в формате logfmt — key=value, разделённые пробелами. В продакшене — json с добавлениями метки времени. Устанавливается в конфигурации запуска приложения.

«Принцип 12f имеет к этому весьма опосредованное отношение, интерфейсы не его авторы изобрели.» — интерфейсы и 12F — параллельные понятия.

«Мьютекс на каждую запись в логи в продакшн сервисе? Это Вы серьёзно, да? Ну и про С# конечно тоже повеселило, спасибо.» — ну а меня веселят ваши нервная реакция и синдром даннинга крюгера. В Go мьютексы бесплатны и не блокируют поток ос, поскольку все инструкции асинхронны. И да, защищать мьютексом в Go всё, что может использоваться конкурентно — это рекомендованные best practices
Код я привёл в другой ветке, он тривиальный. Там требуется ещё garcefull shutdown, но я понятия не имею как это реализуется в windows без сигналов unix.

Такой подход позволяет:
— при разработке и в рабочем окружении не используются сторонние сервисы и зависимости, связанные с логгированием
— разработчику не нужно заниматься маршрутизацией и хранением stdout, это делегируется внешним программам
— поскольку поток событий пишется в stdout гарантированно без буферизации, кеширования и прочих вещей, которые могут создавать накладные расходы, у разработчика есть гарантия, что логгирование не станет узким местом, не создаст доп. нагрузку на GC и в случае C# на асинхронный пул

«надёжное межпроцессное взаимодействие штука не дешёвая.» — это верно, но не в случае перехвата дочернего stdout родительским процессом, в этом случае всё действительно просто

«В проектах какой компании можно встретить реализацию такого подхода к Windows Service?» — не могу сказать. Много ли компаний вообще используют windows service для бизнес кода? не уверен, не видел таких ни разу. В основном для инфраструктурного и системного насколько я могу судить. Разумеется в системном и инфраструктурном программировании 12F подходит не всегда, там много старых гайдланов и различных древних хакерских практик, которые до сих пор в ходу. понятно, что при разработке и работе условного драйвера для видюхи нет практически ничего из того, что предполагает 12F
Хорошо, всё понятно. Вы — не можете.
Это _вы_ не можете, говорите за себя.

play.golang.org/p/yreNlk9bpoM
Вы думаете исключительно о том, _как_ логгировать в поток вывода
Не можете разработать код, который пишет в консоль, и полагаете, что другие не могут? Я пишу всё в консоль и в принципе не задумываюсь о реализации логгирования. Каким образом записи из консоли попадают в итоге в журнал — мне плевать, это решается в момент запуска приложения с помощью инфраструктурного ПО. Если по каким то причинам инфраструктурного ПО не хватает (чего не бывает практически никогда), то я или другой разработчик его создают, ни каких проблем с этим нет. Вы воюете с мельницей, поскольку такой подход к логгированию используется чуть более чем везде. Докер, systemd, облачные сервисы amazon, google cloud, heroku — всё это умеет работать с консольным выводом и полностью соответствует всем рекомендациям 12f, и мне не нужно ничего изобретать.
Вам приходится изобретать способ обернуть своё консольное приложение так, чтобы оно выглядело как Windows service
Я не пишу windows service. Я пишу бизнес фичи в соответствии с гайдлайнами, частью которых является консоль как единственный журнал. Потребуется запускать бизнес фичи в виде windows service — ни каких проблем, это бесплатно. Я в 90% случае даже представления не имею, на какой платформе будет запускаться моё приложение и в какой источник оно будет логгировать.
наплевав при этом на производительность, отказоустойчивость, простоту обслуживания.
Производительность и безопасность коня в вакууме — смешно. Попробуйте аргументировать.
Зона ответственности приложения заканчивается на вызове методов ILogger.Log*whatever*. Что происходит с логами дальше — это уже не забота разработчика.
Да, именно так у меня и есть. Благодаря следованию принципам 12f мои приложения не содержат плотформенных зависимостей, связанных с логгированием. А вот у вас если приложение использует event log windows для логгирования, то оно ни при каких обстоятельствах не будет работать на google cloude. И наоборот — если логгирует в google cloude, то не запустится под windows.
ссылка не имеет абсолютно никакого отношения к вопросу

ссылка про структурное логгирование не имеет ни какого отношения к структурному логгированию? ну ну
правильная реализация многопоточности — это уже непростой код, а шапкозакидательство не свидетельство квалификации. Обычно, наоборот.
Скорее свидетельсво узковатого кругозора у вас. Вы наверное имеете ввиду, что одновременно правильная и простая реализация многопоточности — это не про C#. На C# нельзя просто залочить мьютексом shared mutable state и одидать что это заработает. Ну так я с этим и не спорил. К счастью, я пишу на Go, и мне не сотавляет труда поставить мьютекс там, где есть доступ к стейту, и радоваться жизни.
второй пример дискредитации фактов, которые не укладываются в стройную теорию манифеста
Понятия не имею про azure, но и ничего не имею против неё — мне она фиолетова. Но вы опять не разобрались в вопросе. Azure умеет в докер, следовательно полностью соответсвует 12f в части логгирования. Скорее всего умеет и без докера (но кто в здравом уме будет деплоить C# без докера), просто вы не в курсе (а мне не интересно)
Вы имеете полное право с ним не соглашаться, поэтому ни о каком навязывании речи не идёт.
А давайте тогда я буду говорить «консоль», а вы не будете меня одёргивать.
Это, очевидно, верно,
Я привёл вам факты, которые опровергаю ваше утверждение.
Спасибо за диагноз, так сказать, по фотографии
При чём здесь диагноз?
тогда поясните критерии целесообразности вот этого
Поясню. У меня логии === коснсоль. И, наоборот, всё, что попадает в консоль, автоматически идёт в логи. При разработке я думаю не о том, как логгировать, а о том, что логгировать. Могу вообще не использовать ILogger, а просто выводить в консоль нужный текст. Решение о том, как и куда логгировать — по умолчанию в консоль (в 99 % случаев), в никуда, в файл, базу данных, logstash — принимается при запуске программы, а не в процессе разработки. При этом мне для логгирования наплевать, в каком окружении работает мой сервис, в amazon cloude или в виде службы windows — мне не нужно менять программу, чтобы адаптировать её под произвольный журнал.
Если это можно сделать в 15-20 строк кода — с интересном изучу. Опубликуете?
Зачем? Это элементарные вещи. Вы не можете запустить дочерний процесс или редиректнуть его stdout? Вам в SO тогда наверное, там этого много для любого ЯП
совершенно несложно привести конкретный пример.
погуглил за вас
логгер у нас уже хранит состояние, плюс поддерживает многопоточную запись. Уже есть сомнения в возможности " достаточно простой обёртки над выводом в stdut"
То есть любой конкурентный код у вас по определению не может быть простым? Ну пусть будет так — простой для меня и сложной для вас обёртки. В любом случае речи не шло о том, чтобы писать логгер самому, готовых решение более чем достаточно
Ну а Azure Application Services, Azure Functions, etc.? Тоже объявим дремучими и маргинальными?
Не знаю. На основании чего их следуете такими объявить? Вообще по отзывам админов/девопсов azure cloud — проприетарщина и отвратительное соотношение цена/качество, и не понятно кто его использует и зачем. Может некие «партнёры» по специальным «программам».
явные проблемы в понимании архитектуры.
Это вообще не имеет значения. Называйте как хотите. Не надо навязывать другим своё мнение.
давайте посадим Windows service в докер-контейнер
Эти измышления не уместны здесь. У меня был контраргумент к вашему утверждению «такая инфраструктура журналирования, как описывается в манифесте 12 factor app, просто отсутствует». Очевидно это не верно — я вам показал почему. Вопрос целесообразности я не поднимал, не надо всё мешать в одну кучу. И понимаете вы его не правильно если что. Понятно же, что службы windows разработаны 20-30 лет назад по дремучим гайдлайнам, которые ни кто переделывать не собирается, ни гайдлайны, ни сами службы. Но я с эти и не спорил — не надо приписывать мне то, что у вас в голове. Разработка служб windows — это вообще маргинальная и узкоспециализированная ниша, интересная чуть более чем никому. Какая ниша — такая и инфраструктура, такой и уровень соответствия современным рекомендациям. Когда мне нужно запускать веб-сервис в виде службы windows, я напишу обычный веб-сервис и без проблем запущу его в виде службы и направлю stdout куда мне надо без посторонних «агентов» и докеров. Цена вопроса — ~15-20 строк банального кода. Обсуждать это, тем более об этом спорить — бессмысленно. Не умеете — ни кто вас не заставляет.
Какие, простите, ключи и значения необходимо передавать в каждый метод в стеке,
Любые. Прочитайте об общих понятиях структурного логгирования прежде чем задавать подобные вопросы.
и почему их обязательно необходимо оборачивать в логгер?
Потому что они относятся к логгированию и ни к чему более. Но опять таки ни кто вам не мешает предавать ключ-значение напрямую, без ILogger, или вообще не использовать коль вы не умеете в структурное логгирование.
Это ни какая не грубая ошибка, а нормальное отождествление наиболее распространённого случая. По умолчанию stdout для разработчика — это консоль практически всегда.
А дальше, до введения собственно интерфейса ILogger остаётся один шаг.
А я изначально ничего и не имел против ILogger
в случае с Windows service, приведённом выше, такая инфраструктура журналирования, как описывается в манифесте 12 factor app, просто отсутствует
Элементарно создаётся на пальцах. Докер. nssm.cc Наверняка есть и что-то ещё, просто вы не в курсе
Контейнер зависимостей, динамично выстраеваемый под конкретную среду выполнения, хотя и не без серьёзных недостатков, имеет право на существование, как решение этой потребности.
Нет. Логгер нужно передавать в каждую функцию/метод в качестве параметра, чтобы получить в сообщении предопределённый сверху стека вызовов набор ключ-значение
Элементарно. Запускать бинарник из процесса, который стартует (инсталирует, суспендит, закрывает) службу и выполняет в ней бинарник, при этом перехватывает stdout бинарника и пишет его в системный журнал

Я не говорил, что он предпочтительнее везде и всегда. Иногда в зависимости от задачи и обстоятельств предпочтительнее может быть что угодно — dev/null, консоль, файл, ELK. Но как правило для windows системный журнал — хороший выбор, потому что это стандартный и рекомендованный вендором системный компонент централизованного логгирования + фронтенд.
Ну понятно же, что консоль — это и есть stdout в большинстве случаев.

== вторая, на мой взгляд, ошибочна.
== Простым выводом в stdout тут не отделаешься.

Текстовое сообщение в данном случае — это json с «дополнительными данными и метаданными», для которого ни какие специальные агенты не требуются, а достаточно простой обёртки над выводом в stdut. Инфраструктурное ПО берёт сообщение из stdout и перенаправляет в logstash (или Loki). Смысл постулата — приложение никогда не должно само писать в logstash, loki, или боже упаси напрямую в elasticsearch.

Точно также, только при запуске службы перенаправить stdout из dev/null в системный журнал event log

Я собственно ни разу не против DI. И в контексте DI считаю вполне нормальным использовать ILogger, предоставляющий для ICalculator возможности логгирования.
Пример крайне неудачный. FileLogger продвигает в явном виде антипаттерн, противоречащий 12 factor apps. А именно — логгирование должно производится только в консоль и никуда более.

Во-2, у вас один интерфейс и у него одна зависимость. Для этого нужен DI контейнер, серьёзно?
HTML — это язык, на котором он разговаривает.
HTML — полноценный фреймворк.

Скорее формат сериализации DOM. Если html считать языком, то от языка бизнеса он отличается примерно как язык бабуинов от английского.

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

Вы попробуйте всё же в rpc фреймворки — сразу оцените насколько они упрощают жизнь
Так ведь нет, не получается.

Разрабатывать интерфейс IService не нужно, он генерируется из спеки и является своего рода низкоуровневой деталью реализации апи, используемой фреймворком.

Публиковать реализацию так же не нужно, она сама «публикуется».

ServiceApi и ServiceApiClient генерирует тулза — бесплатно, для этого не нужно прилагать умственных усилий. Вся конфигурация сервера сводится к запуску хттп листенера с указанием урла и прописывания миделварей точно так же как у вас (CORS и т.п ), ни какие редиректы не нужны. Банально прописывается реализация для сгенерированных заглушек и всё. При этом архитектура самого сервера не завязана на DI, а доменную модель можно делать как вам больше нравится — на DI или глобальных переменных или как-то ещё.

Что касается клиента, то ServiceApiClient на C# в данном случае (я пишу на другом ЯП, раньше писал на C#) нужен исключительно для интеграционных и функциональных тестов на апи. И его конфигурация так же сводится к указанию корневого урла сервера.

Далее, если мы не планируем обращаться к ServiceApi из веб приложения браузера, а планируем его юзать из внутренних сервисов, мобильных клиентов и, например, дектопа — то нам нужен не сваггер, а grpc как более универсальная, мощная, надёжная и простая технология. Сваггер — только для веба.

Конкретно для веба генерируется fetch-клиент и типы структур данных сервиса на typescript. Поэтому фронтенд программисту не нужно думать о конечных точках, обработке ошибок хттп и т.п. вещам касательно транспорта. Он получает полностью типизированный и рабочий апи, сгенерированный из спеки OpenApi, так же как и ServiceApiClient для тестов — ServiceApiClient.Foo(Bar). Фронтенд программист так же участвует в разработке спеки, внося в неё требуемые ему фичи. В вашем же случае типизация апи на стороне клиента и транспорт делаются вручную и поддерживаются в актуальном состоянии через боль и слёзы.

1
23 ...

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность