Подсчет количества совпадений в методе жизненного цикла с помощью ColdFusion

Мне нужно отобразить некоторые аналитические данные о том, сколько раз вызывается функция «OnRequestStart», или, скорее, количество обращений в час в нашем внутреннем API, содержащемся в файле .cfc. Желательно через метод жизненного цикла; однако счетчик должен продолжать работу вне жизненного цикла. Я знаю, что это можно легко сделать на других языках, но я новичок в ColdFusion и пытаюсь прочитать документацию, чтобы узнать, есть ли какой-либо метод жизненного цикла, который я могу использовать для этого. Если есть какая-то документация, которой мне не хватает (я пробовал выучить cf за неделю, cfdocs, документация по Adobe), но на самом деле там не так много. Вероятно, это не на 100% ясно, но если возникнут какие-либо разъяснения, я буду рад помочь.

Изменить: я решил, что было бы лучше установить переменную приложения в onApplicationStart и постепенно добавлять 1 к переменной счетчика в начале onRequest. Вот мой пример кода:

Application.cfc:

<CFFUNCTION NAME="OnApplicationStart" ACCESS="PUBLIC" RETURNTYPE="BOOLEAN">
   <cfset Application.timer EQ 0/>
   <cfset Application.counter EQ 0/>
</CFFUNCTION>

somepage.cfm

<tr> 
    <cfoutput> #Application.counter#</cfoutput>
</tr>

Я думал, что это сработает, но получаю сообщение об ошибке Element COUNTER is undefined in APPLICATION. Что-то мне не хватает? Я попытался перезапустить службу CF-сервера и веб-сервер, но безуспешно.

Спасибо всем за вашу помощь


person G.Rose    schedule 22.08.2018    source источник
comment
Вы хотите записать в журнал или просто войти в базу данных или что-то в этом роде? Просто создайте функцию для логирования и вызовите ее в OnRequestStart. Это ваш API или внешний?   -  person Shawn    schedule 22.08.2018
comment
Возможно, напишу в журнал, но мне также нужно где-то отображать количество попаданий. Внутренний API   -  person G.Rose    schedule 22.08.2018
comment
Если это ваш внутренний API, почему бы просто не зарегистрировать его из самого API?   -  person Shawn    schedule 22.08.2018
comment
Я пытаюсь записать это в API   -  person G.Rose    schedule 22.08.2018
comment
Внутри API просто используйте что-то вроде writeLog(text="<API_Name> Called. #application.reqCount# total calls.", type="information", file="apiLog"); в своем API (при условии, что это CF API) и используйте сценарий Redtopia для записи в область application. Но это будет увеличивать его каждый раз, когда вызывается API, пока приложение не было перезапущено. Вам может потребоваться другое разделение времени или более постоянный счет.   -  person Shawn    schedule 22.08.2018
comment
Функция writelog многократно воссоздает файл журнала, правильно?   -  person G.Rose    schedule 22.08.2018
comment
Я считаю, что writeLog() создаст файл в первый раз, а затем будет записывать в него новую строку при каждом вызове API. Это поместит файл в папку журнала CF-сервера. Я не думаю, что в журнале CF есть что-то, что будет управлять вашими файлами журнала (размер, количество и т. Д.), Так что вам придется с этим справиться. Вы можете создать задачу, чтобы переместить файл журнала и переименовать его на нужный вам интервал, тогда при следующем вызове API будет создан новый файл. Я не уверен, может ли атрибут file= в writelog() принимать динамическую переменную (может, включать день или что-то в этом роде).   -  person Shawn    schedule 22.08.2018
comment
Я знаю, что CF Admin может управлять файлами журнала, но я не уверен, обрабатывает ли он все файлы в папке журнала или только стандартные файлы.   -  person Shawn    schedule 22.08.2018
comment
Спасибо, Шон, но я думаю, что не буду использовать файл журнала. Мне не нужны данные постоянно, так как я буду отправлять информацию администраторам после определенного порога.   -  person G.Rose    schedule 23.08.2018
comment
Я хотел бы еще раз предупредить, что область application, вероятно, будет проще всего, но если приложение завершится до достижения вашего порога, вы потеряете свой предыдущий счет. Возможно, вы захотите найти что-нибудь более устойчивое, в зависимости от ваших критериев.   -  person Shawn    schedule 23.08.2018


Ответы (2)


Запишите его в область приложения, в onRequestStart(), включите следующий код:

lock scope="application" type="exclusive" timeout=1 throwontimeout=false {
    if (!application.keyExists("reqCount") {
        application.reqCount= 0;
    }
    application.reqCount++;
}

Тогда вы сможете использовать его там, где вам нужно.

person Redtopia    schedule 22.08.2018
comment
Есть ли какая-нибудь документация, которую вы бы порекомендовали, чтобы я мог полностью понять, что это делает? Спасибо - person G.Rose; 22.08.2018
comment
Отличный ответ! Однако OP не дает понять, нужен ли им счетчик, чтобы жить за пределами жизненного цикла области применения приложения. Ваш ответ будет работать, но OP должен знать, что при перезапуске приложения счетчик сбрасывается. - person Sam M; 22.08.2018
comment
И в зависимости от того, откуда это вызвано, вы захотите проверить, с чего reqCount должно начинаться. Если он из onRequestStart(), то 0 будет работать, но если он вызывается из API, вы захотите использовать 1, поскольку он не будет вызван до первого запуска. - person Shawn; 22.08.2018
comment
@ G.Rose, я не знаю, куда бы вы пошли, чтобы познакомиться с документацией CF, но я полагаю, что есть много ресурсов. Мой ответ предполагает наличие базовых знаний о том, для чего предназначена область применения и как ее использовать. Исключительная блокировка существует, потому что несколько запросов могут выполнять код одновременно. Первое, что я делаю, это проверяю, существует ли переменная reqCount в области приложения. Если нет, он инициализирует его до 0. Затем он увеличивает его. Это не то, что вы хотели бы делать в производственной среде, потому что вы не хотите, чтобы монопольные блокировки выполнялись при каждом запросе. - person Redtopia; 23.08.2018
comment
@Redtopia, этот метод, вероятно, сработает, но он находится в производственной среде, поэтому мне придется найти другой способ. Сэм, спасибо за разъяснения - person G.Rose; 23.08.2018
comment
Как вы думаете, можно ли просто добавлять 1 к переменной вне метода стиля жизни каждый раз, когда вызывается метод OnRequestStart? - person G.Rose; 23.08.2018
comment
@ G.Rose, если вам нужно сделать это в производственной среде, лучше всего будет использовать какой-то аналитический инструмент, который объединяет данные вашего журнала. Подумайте о пожаре и забудьте ... другими словами, вы регистрируете активность и двигаетесь дальше. В противном случае у вас нет выбора, кроме как создать эксклюзивную блокировку для предотвращения состояний гонки. Ведение журнала в базе данных было бы столь же плохим, потому что ваша база данных создала бы блокировку. - person Redtopia; 24.08.2018

Оказывается, самый простой способ сделать это - просто создать переменную вне жизненного цикла или внутри onApplicationStart, а затем увеличивать переменную с каждым onRequestStart. После этого вы можете делать все, что нужно. Одна вещь, которую я сделал по глупости, была помещена <cfset Application.timer EQ 0/> <cfset Application.counter EQ 0/> после тега <cfreturn>. Урок усвоен, ничего не предполагай, исследуй все, ха-ха.

Всем спасибо

person G.Rose    schedule 23.08.2018
comment
Опять же, если ваше приложение или сервер умирают, вы потеряете свой счетчик. Вы можете использовать onApplicationEnd(), чтобы очистить его, если что-то вызывает нормальное завершение работы, но я не думаю, что это сработает при отключении питания или другом сбое сервера. - person Shawn; 23.08.2018