2010-06-04 3 views
2

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

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

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

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

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

+0

Вы можете установить непосредственно перед/сбросить идентификатор потока и после вызова на параллельные биты работы (попробуйте /, наконец, рисунок), и а затем использовать это для ведения журнала? –

ответ

0

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

+0

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

1

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

+0

Мне нравится эта идея, за исключением того, что я не вижу фактического поколения потока. Это из моих рук, благодаря пакету рабочего процесса. – Risser

+0

Чтобы расширить эту идею, предлагаемая здесь задача состоит в том, чтобы помещать в журнал события, связанные с потоком, по цепочке потоков. Если в * точке * во время обработки вы знаете идентификатор транзакции, то вы можете связать ее со всеми событиями журнала, стоящими в очереди. Если вы создаете большое количество событий журнала, эта «очередь» все еще может быть в файловой системе, и вы используете шаг последующей обработки для преобразования threadId -> transactionId. –

0

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

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

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

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

1

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

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

1

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

//In the code:

MDC.put("RemoteAddress", req.getRemoteAddr());

//In the configuration file, add the following:

%X{RemoteAddress}

Детали:

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

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

Смежные вопросы