ОП говорит: «Журналирование Java» не годится.«Да, но вы должны вручную вставлять все вызовы журнала. Не очень приемлемый вариант для большого проекта, не так ли?».
Хорошо, вам нужен способ автоматической вставки пользовательских инструментов в ваше приложение.
Для этого можно использовать наш набор инструментов для реинжиниринга программного обеспечения DMS с интерфейсом Java .DMS предоставляет универсальный механизм для анализа исходного кода, построения AST и таблиц символов, анализа кода (деревьев) для особых случаев и выполнения преобразований в коде (деревьях), в конечном итоге воссоздавая модифицированный код (из модифицированных деревьев).Интерфейс Java позволяет DMS сделать это для Java;В DMS есть много других языковых модулей внешнего интерфейса.
Вам нужно написать преобразование источника в источник DMS, чтобы снабдить запись функции логикой для вывода значений из списка параметров (например, serialize).их эквиваленты "toString"):
tag RecordArguments(a:arguments):statements;
instrument_function_entry rule(r:type,m:identifier,a:arguments,s:stmts):method->method
"\r \m(\a) { \s } "
->
"\r \m(\a) { Call.FunctionEntry(\stringify\(\m\));\RecordArguments\(\a\); { \s } }"
empty_arguments rule () arguments -> statements
"\RecordArguments\(\) " -> ";"
more_arguments rule (args:arguments,a:argument) arguments -> statements
"\RecordArguments\(\args,\a)"
-> "\RecordArguments\(\args\);Call.Argument(\a.toString()))"
То, что делает правило "instrument_function_entry", - это вызывает вызов для записи записи функции и генерирует серию вызовов для записи значений аргумента.Правило empty_arguments обрабатывает базовый случай обработки аргументов no-more-arguments (включая «вообще никаких аргументов»).Правило «more_arguments» обрабатывает список аргументов, выбирая последний, генерируя код для выгрузки этого аргумента и создавая более короткий список оставшихся аргументов, которые будут обработаны тем же правилом или, в конечном итоге, правилом «empty_arguments».
Что это должно произвести для метода:
int X3(char J, array[] X)
{ <code> }
будет
int X3(char J, array[] X)
{ Call.FunctionEntry("X3");
Call.Argument(J.toString());
Call.Argument(X.toString());
{ <code> }
}
Вы можете определить объект "Вызов", как хотите, чтобы записать результаты.Если вы хотите разместить там дополнительные фильтры, чтобы исключить данные из неправильного потока, или между промежутком времени или рядом с каким-либо интересным событием, вы можете это сделать.Это может сильно замедлить ваше приложение, по крайней мере, если вы позволите инструктору делать это при каждом вызове функции в вашем приложении.(Более сложные преобразования могут контролировать, где они применяются).