Регистрация действий в многопоточных приложениях - PullRequest
5 голосов
/ 17 сентября 2008

У меня есть многоуровневое приложение на Java, которое имеет многопоточный уровень доступа к данным, который вызывается из разных точек. Один вызов этого уровня может порождать несколько потоков для распараллеливания запросов к БД.

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

Хотя приложение написано на Java, язык не является ограничением; что мне нужно, так это рекомендации по проектированию, чтобы в итоге реализовать его. В настоящее время мы используем log4j, но не можем получить от него такое поведение.

Ответы [ 7 ]

4 голосов
/ 17 сентября 2008

Вы должны иметь возможность передавать регистратор, поэтому вы создаете регистратор на основе некоторого «общего» для данных задачи - то есть имени пользователя и т. Д. Затем передайте этот регистратор в качестве параметра всем необходимым вам методам. Таким образом, вы сможете установить различные фильтры и / или правила в файле конфигурации log4j. Или очистить выходной файл на основе имени регистратора.

РЕДАКТИРОВАТЬ: также проверьте классы MDC и NDC в log4j. Вы можете добавить туда данные контекста.

4 голосов
/ 17 сентября 2008

Вам также следует взглянуть на вложенный диагностический контекст в log4j. Выдача разных контекстов в регистратор для разных абонентов может помочь вам.

2 голосов
/ 17 сентября 2008

В одном из моих (веб) приложений я использую регистратор ThreadLocal, который записывает информацию о регистрации в StringBuilder. Объект logger инициализируется в методе службы HttpServlet #, если задан параметр трассировки (если он не задан, существует очень быстрый нулевой логгер) Полученный результат либо выгружается в виде HTML-комментария на запрашивающую страницу, либо записывается в файл журнала в одном сегменте.

2 голосов
/ 17 сентября 2008

В log4j вы можете записать имя потока с шаблоном "% t". См. log4j Pattern Layout .

0 голосов
/ 17 сентября 2008

Вам нужно будет передать некоторую структуру слою доступа к данным, которая идентифицирует текущую «активность». Возможно, у вас уже есть «Activity» -класс, который имеет смысл, вы можете использовать экземпляр Logger в качестве Sunny, предложенный , или вы можете использовать третью структуру, чтобы отслеживать контекст действия.

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

Я бы предложил сделать небольшой фасад поверх log4j, который расширяет интерфейс такими методами, как

void debug(Activity activity, String message);

и передачи в нее контекста активности из уровня доступа к данным.

Вам нужно будет внести некоторые изменения в слой доступа к данным, чтобы позволить вам передавать ему текущее действие, но то, как лучше всего это сделать, сильно зависит от текущего интерфейса. Если вы используете шаблон Workspace, вам может потребоваться добавить метод setActivity () в класс Workspace, но другой шаблон интерфейса может потребовать добавления параметра Activity для всех методов.

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

0 голосов
/ 17 сентября 2008

Вы хотите связать объекты логгера с потоками, я думаю. Может помочь переменная ThreadLocal, содержащая экземпляр log4j logger для каждого потока:

http://java.sun.com/javase/6/docs/api/java/lang/ThreadLocal.html

0 голосов
/ 17 сентября 2008

В Java5 (и более поздних версиях) вы можете позвонить

StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();

Проверьте трассу стека на нужную глубину и зарегистрируйте ее соответствующим образом.

В Java 1.4 вы можете получить ту же информацию с помощью

StackTraceElement[] stackTrace = new Exception().getStackTrace();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...