Metering your containers
To use Watson Speech-to-Text Embed containers in production settings, the runtime must be configured to save metering logs to persistent storage. Metering information is included in per-request log messages written to
stdout.
The relevant logs messages can be identified by their JSON structure and the existence of the field total_audio_msec which is the number of milliseconds of audio processed. Below is an example log line from a request:
{"transactionId": "transId-NOTFOUND", "pl-transaction-id": "pl-transId-NOTFOUND", "x-dp-watson-tran-id": "x-dp-watson-tran-id-NOTFOUND", "userId": "userID-NOTFOUND", "bluemix-organization-guid": "orgID-NOTFOUND", "bluemix-region-id": "region-id-NOTFOUND", "bluemix-instance-id": "instance-id-NOTFOUND", "bluemix-plan-id": "plan-id-NOTFOUND", "bluemix-service-id": "service-id-NOTFOUND", "bluemix-space-guid": "space-guid-NOTFOUND", "bluemix-iamid": "iamid-NOTFOUND", "bluemix-crn": "crn-NOTFOUND", "customer_id": "customer_id-NOTFOUND", "consumer_id": "consumer_id-NOTFOUND", "customization_id": "customization_id-NOTFOUND", "acoustic_customization_id": "acoustic_customization_id-NOTFOUND", "logOptout": "0", "serviceApi": "REST", "internal": true, "audioLogFile": "/opt/ibm/chuck.x86_64/logs/2022-10/2022-10-19/payload/37a8eec318d054f84cf335d96badf00d/utt_transId-NOTFOUND_0000.wav", "resultsLogFile": "/opt/ibm/chuck.x86_64/logs/2022-10/2022-10-19/payload/37a8eec318d054f84cf335d96badf00d/result_transId-NOTFOUND_0000.log", "isCustomizationUsed": false, "isAcousticCustomizationUsed": false, "session_start_timestamp": 1666209919.1543539, "cpu_time_at_session_start": 3.03, "timenow": "2022-10-19 20:05:19.560983", "hostname": "d75420b88a09", "model_name": "en-US_Multimedia", "action": "recognize", "action_start_msec": 1666209919154, "final_response_time_msec": 406, "payload_start_msec": 104, "cpu_time_before_payload_start_msec": 80, "cpu_time_msec": 340, "request_completed": 1, "requested_features": {"maxAlternatives": 1, "wantTimestamps": true, "wantWordConfidence": false, "keywordsThreshold": null, "wordAlternativesThreshold": null, "inactivityTimeout": -1, "profanityFilter": true, "useSmartFormatting": false, "firmupSilenceTime": 0, "customizationWeight": null, "diarization": true, "profile": "low_latency", "grammarId": null, "grammarName": null, "grammarSemantics": false, "backgroundAudioSuppression": null, "speechDetectorSensitivity": null, "pciRedact": false, "semanticFirmup": false, "processingMetricsInterval": 1.0, "processingMetrics": false, "customization": false, "acoustic_customization": false, "online_grammars": false, "lowLatency": null, "audioMetrics": false, "wantInterim": false}, "deployment_info": null, "request_number": 0, "first_response_time_msec": 367, "total_audio_msec": 1220, "realtime_factor": 0.239, "busy_time_msec": 291, "utilization": 0.965, "snapshots": {"measurement_time_msec": [], "total_audio_msec": [], "cpu_time_msec": [], "busy_time_msec": [], "audio_received_msec": []}, "speech_msec": 840, "total_words_decoded": 2, "max_chunk_rtf": 0, "model_version": "en-US_Multimedia.v2021-03-03", "input_rtf": 0.005, "latency_from_eos": 0.296, "audio_confidence": 0.935}
The metered metric for Speech-to-Text is Monthly Minutes of speech audio processed. The number of minutes is rounded to a whole number per request. If the duration is less than 1 minute, round up to 1, if greater, round down to the nearest whole
minute. Equivalently, divide the value of total_audio_msec by 60000, apply the floor function, and round up to 1 if the result is 0.
Example Usage - Scraping Logs
A typical production deployment will have a logging system that gathers and persists logs written to stdout of the containers, such as LogDNA. The relevant log messages can be exported by searching for the total_audio_msec field.
Given a set of log files from the runtime container(s), the log files can be processed using the JSON processor jq.
The command below shows an example of how to aggregate the metering metrics across a set of log files assumed to have the .log suffix:
cat *.log | grep 'total_audio_msec' | jq --slurp '[.[] | (.total_audio_msec/60000 | floor) | if . == 0 then 1 else . end] | add'