Журнал Java через несколько потоков - PullRequest
2 голосов
/ 04 июня 2010

У нас есть система, которая использует многопоточность, чтобы она могла параллельно обрабатывать разные биты функциональности. Мы хотели бы найти способ связать все записи журнала для определенной «транзакции» вместе. Обычно можно использовать «threadName», чтобы собрать их вместе, но очевидно, что в многопоточной ситуации это не получается.

Если не передавать ключ транзакции при каждом вызове метода, я не вижу способа связать их вместе. И передача ключа в каждый метод просто ужасна.

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

У кого-нибудь есть предложения?
Спасибо,
Питер

РЕДАКТИРОВАТЬ: К сожалению, я не могу контролировать создание потоков, поскольку все это обрабатывается пакетом рабочего процесса. В противном случае, идея кэширования идентификатора один раз для каждого потока (возможно, в ThreadLocal?), А затем установить его для новых потоков по мере их создания, является хорошей идеей. Я могу попробовать это в любом случае.

Ответы [ 6 ]

1 голос
/ 04 июня 2010

Однако вы упомянули, что ваша транзакция охватывает более одного потока, посмотрите, как log4j справляется с привязкой дополнительной информации к текущему потоку с классами MDC и NDC. Он использует ThreadLocal, как вам советовали ранее, но интересно то, как log4j внедряет данные в сообщения журнала.

//In the code:</p> <p>MDC.put("RemoteAddress", req.getRemoteAddr());</p> <p>//In the configuration file, add the following:</p> <p>%X{RemoteAddress}

подробности:

http://onjava.com/pub/a/onjava/2002/08/07/log4j.html?page=3

http://wiki.apache.org/logging-log4j/NDCvsMDC

1 голос
/ 04 июня 2010

Это прекрасный пример для кроссов AspectJ. Если вы знаете методы, которые вызываются, вы можете установить на них перехватчики и динамически связывать их.

Эта статья предоставит вам несколько вариантов http://www.ibm.com/developerworks/java/library/j-logging/

1 голос
/ 04 июня 2010

Вы можете создать глобально доступный Map, который сопоставит имя Thread с его текущим идентификатором транзакции. После начала новой задачи сгенерируйте GUID для этой транзакции и зарегистрируйте поток непосредственно в Map. Сделайте то же самое для любых Thread s, которые появляются для выполнения той же задачи. Затем, когда вам нужно что-то зарегистрировать, вы можете просто найти идентификатор транзакции из глобального Map, основываясь на текущем имени Thread. (Немного туповато, но должно работать)

0 голосов
/ 04 июня 2010

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

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

0 голосов
/ 04 июня 2010

Если вы регистрируетесь, то у вас должен быть какой-то объект логгера. У вас должен быть отдельный экземпляр в каждой ветке.

  • добавить метод с именем setID (String id).
  • Когда он инициализируется в вашем потоке, установите уникальный идентификатор, используя метод.
  • добавьте установленный iD к каждой записи в журнале.
0 голосов
/ 04 июня 2010

Как насчет именования ваших потоков, чтобы они включали идентификатор транзакции? Быстро и грязно, правда, но это должно работать (пока вам не понадобится имя потока для чего-то другого или вы не начнете повторно использовать потоки в пуле потоков).

...