log4j ?

Dec. 24th, 2021 01:04 pm
malyj_gorgan: (Default)
[personal profile] malyj_gorgan
Слухайте, а хтось може в парі абзаців пояснити, що то таке сабж і з чим його їдят? Дідько з нею, з його vulterability'ею, я хочу зрозуміти, чим був такий хороший чи зручний чи потрібний сам log4j, що та вульнерабіліті виявилася такою проблємною? Тільки пояснити так, на хлопский розум, без відсилань в непотрібні абревіатури.
Дякую!

Date: 2021-12-24 10:11 pm (UTC)
From: [personal profile] sassa_nf
log4j просто означає logging для джави.

Не знаю, чи треба пояснювати logging: це процес конспектування процесу виконання якого-небудь процесу і є ключовим артефактом у діагностиці несправностей систем. Таким чином, оскільки logs - ключовий артефакт, logging роблять усі. Так склалось, що у самій джаві система logging була недолуга та недосконала, так з'явилась opensource бібліотека log4j, яку використовують, можна сказати, усі системи на джаві. Ну, і the rest is history.
Edited Date: 2021-12-24 10:13 pm (UTC)

Date: 2021-12-25 09:54 am (UTC)
From: [personal profile] sassa_nf
ну, там окремі фічі життя полегшують, а всі разом - діра.

log enrichment - додавати потрібні контекстні дані до логів, які або замахаєшся додавати сам, або забудеш. Так з'являється потреба ${ctx.something}.

remote log destination - писати в локальний файл - це годиться для невеликої кількості процесів. Якщо у нас ферма із кількасот або тисяч процесів, з'являється потреба скидати все в одне місце. (ну і, звісно, enrich логи ще й ${ctx.hostname})

(скажімо, з отих двох можна побудувати ще й log censoring - фільтрувати або обскурувати потрібні контекстні дані, залежно від log destination. gdpr, і таке інше)

different types of log destination - а що, є один-єдиний стандарт і протокол передачі логів і одна-єдина архітектура організації процесу передачі логів?

ну, і от тепер все разом взяти докупи - маємо діру. З одного боку щось виймати з контексту - класна і потрібна річ, з іншого боку - якщо для контексту використовувати JNDI, маємо змогу з контексту виймати arbitrary stuff, або зациклити. Ну, і от arbitrary stuff, виявляється, може бути вказівкою JNDI піти поговорити з іншим сервером, який підтримується JNDI - наприклад, лівий LDAP. Але це вже пішли абревіатури.

Date: 2021-12-30 06:12 am (UTC)
From: [personal profile] mprotsenko
Чекаю, коли хтось зламає github або, краще, Atlassian suite і вкраде пів-інтернету.

Сенсу нема. :)

Якщо хтось вкраде наш source code - то (а) нічого особливо секретного в 99% коду він не знайде, усі ідеї давно є публічними, (б) без відповідної інфраструктури (включно з людьми) фіг ти той код запустиш.
Edited Date: 2021-12-30 06:14 am (UTC)

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-30 11:44 pm (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 02:15 am (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 02:37 am (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 05:13 am (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 05:58 pm (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 08:40 pm (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 08:53 pm (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 06:04 pm (UTC) - Expand

Date: 2021-12-30 06:19 am (UTC)
From: [personal profile] mprotsenko
Як з цим боротися -- не знаю.

Одягаю Captain Obvious' cape: треба оптимізувати процеси під MTTR, бо спроба оптимізувати під MTTF зазвичай веде до погіршення як MTTF, так і MTTR.

(Я пам'ятаю, ти просив без абревіатур, вибач!)

UPD: мова, звісно, не про safety-critical інфраструктуру, там інші проблеми, і інші методи їх вирішення.
Edited Date: 2021-12-30 09:37 am (UTC)

Date: 2021-12-30 09:27 am (UTC)
From: [personal profile] mprotsenko
А ще весело, якщо ці процеси ще належать різним сервісам, і треба прослідкувати за тим, як запитання скаче по різним сервісам (додати trace ID в контекст логів). А для того, щоб життя не здавалося медом - зберігати контекст в треді не можна, бо в нас велике навантаження і тред на запит ми не можемо дозволити, бо ніяких тредпулів не вистачить (а замість того треба реактивну модель та non-blocking IO).

З стандартними рішеннями на кшталт grpc+opentracing+log4j усе реалізується невеличким інтерсептором буквально на 5 рядків без втрати перформансу. А ось як цей довольно банальний сценарій реалізувати через System.out.println? (Про це і много чого іншого читайте в свіжому номері журналу "Ніяк".)

Сорі, "музикою навіяло" (с)
Edited Date: 2021-12-30 09:28 am (UTC)

Date: 2021-12-30 12:55 pm (UTC)
From: [personal profile] sassa_nf
о, як цікаво. Добре, що ви згадали про тредпули, реактивну модель та non-blocking IO. Я якраз нещодавно розмірковував, що саме за цією модою стоїть, окрім віри, що вона рятує від купи threads, та workload-specific виграш у приблизно 15%. Не допоможете розібратись?

Ну, от візьмемо нижчезгадані 20K qps. Якщо response time 1 ms, то нам потрібно всього 20 threads. Це не такий і великий thread pool. Якщо ми візьмемо context switch за 50 мікросекунд, реактивна модель нам тут може подарувати десь 5% CPU на кожен eliminated context switch. Якщо ми позбуваємось 2....4 context switches, то виграємо десь 15% response time. Непогано, але звертаю увагу, що справа не у unmanageably large number of threads, і виграш workload-specific.

Для масштабу, розглянемо випадок 20K qps із response time 50ms. Тут би нам було потрібно 1000 threads, це забагато для одного невеличкого процесу. Але ми мусимо знати ще одне невідоме: скільки часу ми проводимо на CPU. (Це саме невідоме присутнє і у випадку з response time of 1 ms, але там ми можемо повністю ігнорувати це питання.) Якщо 1ms, то нам уже потрібно 20 CPUs - це не такий вже і малий процес. Ну, і тепер уже можна розглянути питання, а що ми втратимо, якщо ускладнимо реалізацію сервісу, і введемо thread pools обмеженого розміру та черги, де б запити проводили решту часу, тобто, 49ms. Цього разу context switch - це ледве 0.1% часу, і ми можемо собі дозволити 50 context switches before it becomes a measurable problem.

Тобто, 1000 threads таки з'являється, але для великих сервісів ми, по-перше, можемо собі дозволити, а по-друге, можемо таки зменшити кількість threads.

Мораль цієї історії така: якщо ми можемо використати CPU повністю, то ми CPU-bound, і реактивна модель нам дарує the cost of context switch; якщо ми не можемо використати CPU повністю, то ми bound на якомусь іншому ресурсі, і реактивна модель нічого не поліпшує, а лише ускладнює софт. На пітоні та nodejs реактивна модель - єдина можлива; а от на інших мовах треба дивитись.

Ну, і питання: це схоже на правду? Що я пропустив?


(У дужках додам, що реактивна модель і non-blocking IO нам ще дають inversion of control, який є наслідком CPS, але по-перше ніхто насправді цим не користується, бо API немає, а muxer пишуть одиниці (це, власне, netty і т.ін.), а по-друге люди геть про це не згадують, а обмежуються розмовами про розміри thread pools)

Date: 2021-12-30 06:08 pm (UTC)
From: [personal profile] mprotsenko
Класне питання!

Short answer: так, в 90%+ випадках реактивна модель лише занадто ускладнює код і нафіг не потрібна.

Long answer: є низка випадків, де без реактивщини ніяк, я спробую згадати те, що бачив (і 100% щось забуду :) ).



1) High load. Ті самі 20к RPS перемножити на купу серверів. Виграш в 15% на навантаженні, яке створює computing costs в USD10М за рік - це USD1.5М економії. Якщо код ускладнюється настільки, що треба найняти ще одного інженера чи інженерку за USD500К - все одно автор реактивного коду отримає річний бонус. :)

А якщо рахунок USD100М? А якщо USD1-2-5B? Отож бо. Останнє, звісно, не такий частий приклад, але USD10-100М - не така вже і аберація.



2) High latency. У біллінгу, наприклад, payment processors' SLA часто гарантують відповідь з P99 latency 60s. s, not ms.

І тут навіть 1К RPS нас вбиває.



3) Ultra-low latency та non-linear context switch cost growth. Якщо ми працюємо над системою, де нам треба гарантувати under 1 ms latency, то навіть fixed cost of switching between 2 threads (2-7 microseconds) - це вже помітний імпакт. А в реальному світі, коли мова йдеться про switching между десятками чи сотнями тредів - то це вже буде high double digits (40-70 microseconds).

100% щось забув, але як в тому мемі - "йой, най буде".



Резюме: усе, що я згадав, аж ніяк не суперечить моралі про bottleneck.

Але реактивна модель дозволяє нам наблизитися до більш ефективного використання як CPU, так і IO, і як наслідок - в низці випадків (невеликої, але і не такої малої, щоб її можна було ігнорувати в індустрії в цілому) - отримати реальну економію, від грубих грошей до latency.

Edited Date: 2021-12-30 06:09 pm (UTC)

(no subject)

From: [personal profile] sassa_nf - Date: 2021-12-30 11:54 pm (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 12:14 am (UTC) - Expand

(no subject)

From: [personal profile] sassa_nf - Date: 2021-12-31 09:56 am (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 05:37 pm (UTC) - Expand

Date: 2021-12-30 10:25 pm (UTC)
From: [personal profile] mprotsenko
і введемо thread pools обмеженого розміру та черги, де б запити проводили решту часу, тобто, 49ms

Перечитав і подумав - чи не є реактивною моделлю, але вже без blocking IO? Ні, звісно, так теж можна, але це теж ускладнює код, ні?

(no subject)

From: [personal profile] sassa_nf - Date: 2021-12-30 11:34 pm (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 12:04 am (UTC) - Expand

(no subject)

From: [personal profile] sassa_nf - Date: 2021-12-31 10:16 am (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 05:31 pm (UTC) - Expand

(no subject)

From: [personal profile] sassa_nf - Date: 2022-01-03 01:35 pm (UTC) - Expand

Date: 2021-12-30 06:07 am (UTC)
From: [personal profile] mprotsenko
Ще можна додати, що log4j2 мав (підозрюю, що і зараз має, але ліньки перевіряти) найкращий перфоманс.

При 10-20к RPS на сервер перформанс logging системи - це не така вже й тривіальна проблема.

І порада писати все в System.out тут є дуже шкідливою. Починаючи з того, що це не дуже ефективно з точки зору перформансу, і закінчуючи тім, що якщо ти хочеш мати можливість налаштовувати logging level динамічно (тут не друкувати DEBUG-level logs, а тут друкувати), то кожен System.out.println доведеться загортати в "if", і можливо навіть не один (що, собсна, теж не айс з точки зору перформансу).
Edited Date: 2021-12-30 06:30 am (UTC)

Date: 2021-12-30 11:48 am (UTC)
From: [personal profile] sassa_nf
слушно.

Але загортати в "if" не така вже й performance проблема, якщо log level - фіксована величина. Власне, логер просто ховає цей самий "if" всередину.

Date: 2021-12-30 06:25 pm (UTC)
From: [personal profile] mprotsenko
так.

ускладнюємо задачу - debug-level logs друкуємо не для всіх, а тільки для бета-тестерів. :)

Date: 2021-12-24 10:44 pm (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi

Казалось бы, пиши в System.out, да и все. Но людям хочется поконфигурировать, хочется писать в файлы по какой-нибудь policy, хочется ротацию файлов, вот это все. Самим лень писать (мне б не лень было, если случись), и используют эту жопу. А в этой жопе всякие прибамбасы вставлены, "нормальным людям" (вроде меня) не нужные. Типа "а давайте сходим на какой-нибудь сервер, чтобы что-нибудь еще вставить". И вот это вот "сходим куда-нибудь, а потом вычислим на месте, что прислали" - это большая дыра. Вычислить же можно и sudo rm -rf /.

Date: 2021-12-24 11:21 pm (UTC)
From: [personal profile] sassa_nf
На поверхні - так, пиши собі в system.out

А насправді logs must be structured. Коли просто купа тексту в файлі - можна лише eyeball it і grep. Коли у вас 10 тисяч різних процесів, які взаємодіють між собою, гра в діагностику стає набагато складнішою.

Date: 2021-12-24 11:29 pm (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi

Видимо, мне это как-то не особо всегда надо было. Грепа хватало; вот и сейчас хватает. Есть какие-то тулзы, я их все забываю. Но мне удобнее прямой доступ; если чо, так я и на скале наваляю выборку моей хрени.

Собственно, позавчера именно выдернул данные с помощью split (was it csplit?) и всякого такого, типа интеллиджея. Удобно, вставил потом эти данные в юниттест.

(Собственно, идея добираться до данных через скалу только что и пришла в голову; так и буду. Биг дил,

"scp theserver:/something/logs/my.log my.log" !
Source.fromFile("my.log").readLines.filter....

Был бы доступ только.

Date: 2021-12-25 10:11 am (UTC)
From: [personal profile] sassa_nf
тут кілька питань, найпростіше з яких - а звідки знати, з якого сервера зкачувати логи? і про логи якого процесу на тому сервері йде мова?

Для ілюстрації. Маємо понад два десятки датацентрів, у кожному десятки, а в деяких і сотні машин, на них із десяток контейнерів, у кожному по одному-два-три процеси. Маємо також користувача, який каже, що йому видають 429 - overload. Як дійти від цього до знання, що упав один кластер in-memory cache, і тому отакі і отакі процеси тепер failed over до бази даних, яка не встигає, а в результаті - pile up of requests на сервісі кілька hops away від сервісу, який власне розмовляє з базою даних?

Нас рятує можливість подивитись на весь зоопарк у кібані. А для цього потрібно мати логи всього-всього в "одному" місці, а не на окремих серверах, і індексувати це по важливих аспектах, а не грепати все підряд тексти всіх повідомлень, щоб можна було швидко визначати, на які сервери треба подивитись уважніше.

Date: 2021-12-25 01:53 pm (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi

О! Действительно же. Убедительный пример.

Кстати, я не понимаю, у нас в HealthExpense было 500 серверов - и вот не припомню что-то проблем. Странно. Хм.

(no subject)

From: [personal profile] sassa_nf - Date: 2021-12-25 09:44 pm (UTC) - Expand

(no subject)

From: [personal profile] juan_gandhi - Date: 2021-12-26 12:07 am (UTC) - Expand

(no subject)

From: [personal profile] sassa_nf - Date: 2021-12-26 12:33 am (UTC) - Expand

(no subject)

From: [personal profile] juan_gandhi - Date: 2021-12-26 01:04 am (UTC) - Expand

(no subject)

From: [personal profile] sassa_nf - Date: 2021-12-26 02:42 am (UTC) - Expand

Date: 2021-12-25 12:13 am (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi

Вот я тоже так же на эту хрень смотрю. Попроще надо. Но sassa-nf может разъяснить необходимость всякой такой фигни. Хорошо не в базу данных пишем логи.

Date: 2021-12-25 05:55 pm (UTC)
From: [personal profile] sassa_nf
Ну, так ось ELK і маємо: elastic search, logstash, kebana, чи щось таке :)

(no subject)

From: [personal profile] sassa_nf - Date: 2021-12-26 01:02 am (UTC) - Expand

(no subject)

From: [personal profile] sassa_nf - Date: 2021-12-30 11:47 pm (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 12:40 am (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 02:23 am (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 05:22 pm (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 07:51 pm (UTC) - Expand

(no subject)

From: [personal profile] mprotsenko - Date: 2021-12-31 08:03 pm (UTC) - Expand

Date: 2021-12-25 07:29 pm (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi

Во, прекрасное решение. И если не брать логи, то довольно стандартное. Data Lake. Ну так и логи туда же можно фигачить. Огромное спасибо за идейку.

(no subject)

From: [personal profile] sassa_nf - Date: 2021-12-25 09:14 pm (UTC) - Expand

Profile

malyj_gorgan: (Default)
malyj_gorgan

June 2025

S M T W T F S
12 345 67
89 1011 121314
15161718192021
22232425262728
2930     

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 17th, 2025 08:12 pm
Powered by Dreamwidth Studios