diff --git a/README.md b/README.md index e8285f23b..21150df06 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ for more details. The information below outlines setting up the server for development or your own environment. For general information on deploying Django see https://docs.djangoproject.com/en/1.11/howto/deployment/. -NOTE: Internal software engineers or other interested parties should follow the documentation for running a Dockerized local development enviornment. For more information see https://github.com/CMSgov/bluebutton-web-server/blob/master/docker-compose/readme.md. +NOTE: Internal software engineers or other interested parties should follow the documentation for running a Docker compose based local development enviornment. For more information see https://github.com/CMSgov/bluebutton-web-server/blob/master/docker-compose/readme.md. Setup ----- diff --git a/apps/dot_ext/loggers.py b/apps/dot_ext/loggers.py index 57d1926a8..0667a12df 100644 --- a/apps/dot_ext/loggers.py +++ b/apps/dot_ext/loggers.py @@ -73,6 +73,7 @@ def create_session_auth_flow_trace(request): client_id_param = request.GET.get("client_id", None) auth_pkce_method = request.GET.get("code_challenge_method", None) + auth_language = request.GET.get("lang", None) if client_id_param: try: @@ -86,6 +87,7 @@ def create_session_auth_flow_trace(request): "auth_require_demographic_scopes": str(application.require_demographic_scopes), "auth_client_id": application.client_id, "auth_pkce_method": auth_pkce_method, + "auth_language": auth_language, } set_session_auth_flow_trace(request, auth_flow_dict) @@ -94,7 +96,8 @@ def create_session_auth_flow_trace(request): with transaction.atomic(): AuthFlowUuid.objects.create(auth_uuid=new_auth_uuid, client_id=application.client_id, - auth_pkce_method=auth_pkce_method) + auth_pkce_method=auth_pkce_method, + auth_language=auth_language) except IntegrityError: pass except Application.DoesNotExist: @@ -106,6 +109,7 @@ def create_session_auth_flow_trace(request): "auth_require_demographic_scopes": "", "auth_client_id": "", "auth_pkce_method": "", + "auth_language": "", } set_session_auth_flow_trace(request, auth_flow_dict) @@ -160,6 +164,8 @@ def set_session_values_from_auth_flow_uuid(request, auth_flow_uuid): request.session['auth_crosswalk_action'] = auth_flow_uuid.auth_crosswalk_action if auth_flow_uuid.auth_share_demographic_scopes is not None: request.session['auth_share_demographic_scopes'] = str(auth_flow_uuid.auth_share_demographic_scopes) + if auth_flow_uuid.auth_language is not None: + request.session['auth_language'] = auth_flow_uuid.auth_language try: application = Application.objects.get(client_id=auth_flow_uuid.client_id) diff --git a/apps/dot_ext/migrations/0008_authflowuuid_auth_language_and_more.py b/apps/dot_ext/migrations/0008_authflowuuid_auth_language_and_more.py new file mode 100644 index 000000000..64bcce056 --- /dev/null +++ b/apps/dot_ext/migrations/0008_authflowuuid_auth_language_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 4.2.11 on 2024-07-07 22:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dot_ext', '0007_merge_20231020_2004'), + ] + + operations = [ + migrations.AddField( + model_name='authflowuuid', + name='auth_language', + field=models.CharField(max_length=12, null=True), + ), + migrations.AddField( + model_name='authflowuuidcopy', + name='auth_language', + field=models.CharField(max_length=12, null=True), + ), + migrations.AlterField( + model_name='application', + name='data_access_type', + field=models.CharField(choices=[('ONE_TIME', 'ONE_TIME - No refresh token needed.'), ('RESEARCH_STUDY', 'RESEARCH_STUDY - No expiration.'), ('THIRTEEN_MONTH', 'THIRTEEN_MONTH - Access expires in 13-months.')], default='THIRTEEN_MONTH', max_length=16, null=True, verbose_name='Data Access Type:'), + ), + ] diff --git a/apps/dot_ext/models.py b/apps/dot_ext/models.py index e8ffbaa10..7e4cb0442 100644 --- a/apps/dot_ext/models.py +++ b/apps/dot_ext/models.py @@ -431,6 +431,7 @@ class AuthFlowUuid(models.Model): created = models.DateTimeField(auto_now_add=True, null=True) auth_crosswalk_action = models.CharField(max_length=1, null=True) auth_share_demographic_scopes = models.BooleanField(null=True) + auth_language = models.CharField(max_length=12, null=True) def __str__(self): return str(self.auth_uuid) @@ -463,6 +464,7 @@ class AuthFlowUuidCopy(models.Model): created = models.DateTimeField(null=True) auth_crosswalk_action = models.CharField(max_length=1, null=True) auth_share_demographic_scopes = models.BooleanField(null=True) + auth_language = models.CharField(max_length=12, null=True) def __str__(self): return str(self.auth_uuid) diff --git a/apps/fhir/server/loggers.py b/apps/fhir/server/loggers.py index be4597b0b..2fb4f0ba5 100644 --- a/apps/fhir/server/loggers.py +++ b/apps/fhir/server/loggers.py @@ -1,5 +1,6 @@ import apps.logging.request_logger as logging +from apps.logging.utils import lookup_language """ Logger functions for fhir/server module @@ -13,6 +14,8 @@ def log_match_fhir_id(request, fhir_id, mbi_hash, hicn_hash, used in match_fhir_id() ''' match_fhir_id_logger = logging.getLogger(logging.AUDIT_AUTHN_MATCH_FHIR_ID_LOGGER, request) + # splunk dashboard auth flow baseSearch4 + lang = lookup_language(request) match_fhir_id_logger.info({ "type": "fhir.server.authentication.match_fhir_id", "fhir_id": fhir_id, @@ -21,4 +24,5 @@ def log_match_fhir_id(request, fhir_id, mbi_hash, hicn_hash, "match_found": match_found, "hash_lookup_type": hash_lookup_type, "hash_lookup_mesg": hash_lookup_mesg, + "auth_language": lang, }) diff --git a/apps/logging/serializers.py b/apps/logging/serializers.py index 9e16fd89b..0a88b1965 100644 --- a/apps/logging/serializers.py +++ b/apps/logging/serializers.py @@ -1,5 +1,6 @@ import json import hashlib +from apps.logging.utils import lookup_language class DataAccessGrantSerializer: @@ -39,9 +40,10 @@ class Token: tkn = None action = None - def __init__(self, obj, action=None): + def __init__(self, obj, action=None, request=None): self.tkn = obj self.action = action + self.request = request def to_dict(self): # seems like this should be a serializer @@ -56,7 +58,8 @@ def to_dict(self): scopes = " ".join(scopes_dict.keys()) else: scopes = "" - + # splunk dashboard auth flow dashboard baseSearch12 + lang = lookup_language(self.request) result = { "type": "AccessToken", "action": self.action, @@ -84,6 +87,7 @@ def to_dict(self): "fhir_id": getattr(crosswalk, "fhir_id", None), "user_id_type": getattr(crosswalk, "user_id_type", None), }, + "auth_language": lang, } return result diff --git a/apps/logging/signals.py b/apps/logging/signals.py index a0046ef4c..0f8ae2e80 100644 --- a/apps/logging/signals.py +++ b/apps/logging/signals.py @@ -28,12 +28,14 @@ FHIRResponseForAuth, ) +from apps.logging.utils import lookup_language + @receiver(app_authorized) def handle_token_created(sender, request, token, **kwargs): # Get auth flow dict from session for logging token_logger = logging.getLogger(logging.AUDIT_AUTHZ_TOKEN_LOGGER, request) - token_logger.info(Token(token, action="authorized").to_dict()) + token_logger.info(Token(token, action="authorized", request=request).to_dict()) @receiver(beneficiary_authorized_application) @@ -62,7 +64,8 @@ def handle_app_authorized(sender, request, auth_status, auth_status_code, user, # TODO consider logging exception name here # once we get the generic logger hooked up pass - + # splunk dashboard auth flow baseSearch11 + lang = lookup_language(request) log_dict = { "type": "Authorization", "auth_status": auth_status, @@ -83,6 +86,7 @@ def handle_app_authorized(sender, request, auth_status, auth_status_code, user, "access_token_delete_cnt": access_token_delete_cnt, "refresh_token_delete_cnt": access_token_delete_cnt, "data_access_grant_delete_cnt": data_access_grant_delete_cnt, + "auth_language": lang, } token_logger.info(log_dict) diff --git a/apps/logging/utils.py b/apps/logging/utils.py index 3c8e2a8a6..48522aa15 100644 --- a/apps/logging/utils.py +++ b/apps/logging/utils.py @@ -1,12 +1,27 @@ import io import apps.logging.request_logger as logging +from apps.dot_ext.loggers import ( + get_session_auth_flow_trace, +) """ Utility functions for logging, and logging manipulations (used in tests) """ +def lookup_language(request): + # keep lang code from session if presents + # otherwise grab it from parameters + if request is not None: + auth_dict = get_session_auth_flow_trace(request) + qparam_lang = request.GET.get('lang', request.GET.get('Lang', "")) + qparam_lang = qparam_lang if qparam_lang else request.POST.get('lang', request.POST.get('Lang', "")) + return auth_dict.get('auth_language', qparam_lang) + else: + return "" + + def format_timestamp(dt): """ Returns an ISO 6801 format string in UTC that works well with AWS Glue/Athena diff --git a/apps/mymedicare_cb/authorization.py b/apps/mymedicare_cb/authorization.py index 328c4d790..8a4583c58 100644 --- a/apps/mymedicare_cb/authorization.py +++ b/apps/mymedicare_cb/authorization.py @@ -14,6 +14,7 @@ from .signals import response_hook_wrapper from .validators import is_mbi_format_valid, is_mbi_format_synthetic +from apps.logging.utils import lookup_language MSG_SLS_RESP_MISSING_AUTHTOKEN = "Exchange auth_token is missing in response error" @@ -365,7 +366,8 @@ def validate_asserts(self, request, asserts, err_enum): # asserts is a list of tuple : (boolean expression, err message) # iterate boolean expressions and log err message if the expression evalaute to true logger = logging.getLogger(logging.AUDIT_AUTHN_SLS_LOGGER, request) - + # splunk dashboard auth flow dashboard baseSearch3 + lang = lookup_language(request) log_dict = { "type": "Authentication:start", "sls_status": "FAIL", @@ -380,6 +382,7 @@ def validate_asserts(self, request, asserts, err_enum): "sls_mbi_format_synthetic": None, "sls_hicn_hash": None, "sls_mbi_hash": None, + "auth_language": lang, } for t in asserts: @@ -413,7 +416,8 @@ def validate_asserts(self, request, asserts, err_enum): def log_event(self, request, extra): logger = logging.getLogger(logging.AUDIT_AUTHN_SLS_LOGGER, request) - + # splunk dashboard auth flow dashboard baseSearch3 + lang = lookup_language(request) log_dict = { "type": "Authentication:start", "sub": self.user_id, @@ -428,6 +432,7 @@ def log_event(self, request, extra): "sls_mbi_format_synthetic": self.mbi_format_synthetic, "sls_hicn_hash": self.hicn_hash, "sls_mbi_hash": self.mbi_hash, + "auth_language": lang, } log_dict.update(extra) @@ -435,10 +440,13 @@ def log_event(self, request, extra): def log_authn_success(self, request, extra): logger = logging.getLogger(logging.AUDIT_AUTHN_SLS_LOGGER, request) + # splunk dashboard auth flow dashboard baseSearch7 + lang = lookup_language(request) log_dict = { "type": "Authentication:success", "sub": self.user_id, "user": None, + "auth_language": lang, } log_dict.update(extra) logger.info(log_dict) diff --git a/apps/mymedicare_cb/models.py b/apps/mymedicare_cb/models.py index 17d0cefd8..2527df402 100644 --- a/apps/mymedicare_cb/models.py +++ b/apps/mymedicare_cb/models.py @@ -11,6 +11,7 @@ from apps.fhir.server.authentication import match_fhir_id from .authorization import OAuth2ConfigSLSx, MedicareCallbackExceptionType +from apps.logging.utils import lookup_language class BBMyMedicareCallbackCrosswalkCreateException(APIException): @@ -56,7 +57,8 @@ def get_and_update_user(slsx_client: OAuth2ConfigSLSx, request=None): mbi_hash=slsx_client.mbi_hash, hicn_hash=slsx_client.hicn_hash, request=request ) - + # splunk auth flow baseSearch5 baseSearch6a + lang = lookup_language(request) log_dict = { "type": "mymedicare_cb:get_and_update_user", "subject": slsx_client.user_id, @@ -66,6 +68,7 @@ def get_and_update_user(slsx_client: OAuth2ConfigSLSx, request=None): "hash_lookup_type": hash_lookup_type, "crosswalk": {}, "crosswalk_before": {}, + "auth_language": lang, } # Init for types of crosswalk updates. @@ -176,7 +179,8 @@ def get_and_update_user(slsx_client: OAuth2ConfigSLSx, request=None): def create_beneficiary_record(slsx_client: OAuth2ConfigSLSx, fhir_id=None, user_id_type="H", request=None): logger = logging.getLogger(logging.AUDIT_AUTHN_MED_CALLBACK_LOGGER, request) - + # splunk dashboard auth flow baseSearch6b + lang = lookup_language(request) log_dict = { "type": "mymedicare_cb:create_beneficiary_record", "username": slsx_client.user_id, @@ -184,6 +188,7 @@ def create_beneficiary_record(slsx_client: OAuth2ConfigSLSx, fhir_id=None, user_ "user_mbi_hash": slsx_client.mbi_hash, "user_hicn_hash": slsx_client.hicn_hash, "crosswalk": {}, + "auth_language": lang, } _validate_asserts(logger, log_dict, [ diff --git a/apps/testclient/templates/authorize.html b/apps/testclient/templates/authorize.html index ffb6beacb..e2662fada 100644 --- a/apps/testclient/templates/authorize.html +++ b/apps/testclient/templates/authorize.html @@ -39,6 +39,9 @@

You'll need sample beneficiary credentials to lo
Authorize as a Beneficiary (Spanish) +
+ Authorize as a Beneficiary (medicare.gov login in Spanish) +
diff --git a/apps/testclient/views.py b/apps/testclient/views.py index e6cf45cb0..f9068da8f 100644 --- a/apps/testclient/views.py +++ b/apps/testclient/views.py @@ -111,7 +111,7 @@ def restart(request): @waffle_switch('enable_testclient') def callback(request): - # Authorization has been denied or another error has occured, remove token if existing + # Authorization has been denied or another error has occurred, remove token if existing # and redirect to home page view to force re-authorization if 'error' in request.GET: if 'token' in request.session: diff --git a/splunk/authorization_flow_dashboard_clone.xml b/splunk/authorization_flow_dashboard_clone.xml new file mode 100644 index 000000000..c5ed97075 --- /dev/null +++ b/splunk/authorization_flow_dashboard_clone.xml @@ -0,0 +1,4363 @@ +
+ + + Dashboard panels related to the authorization flow log tracing + + + + + index=bluebutton source="/var/log/pyapps/perf_mon.log*" host=$bbEnv$ env=$bbEnvLabel$ $authAppNameExpr$ | spath "message.auth_language" | search "message.auth_language"="$langPattern$" | spath "message.path" | search "message.path"="/$apiVersionsPattern$/o/authorize/" | fields time message.auth_uuid message.auth_app_name message.ip_addr message.response_code message.path message.auth_pkce_method + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + + + + index=bluebutton source="/var/log/pyapps/perf_mon.log*" host=$bbEnv$ env=$bbEnvLabel$ $authAppNameExpr$ | spath "message.auth_language" | search "message.auth_language"="$langPattern$" | spath "message.path" | search "message.path"="/mymedicare/login" | fields time message.auth_uuid message.auth_app_name message.ip_addr message.auth_pkce_method message.response_code message.location + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + + + + index=bluebutton source="/var/log/pyapps/perf_mon.log*" host=$bbEnv$ env=$bbEnvLabel$ $authAppNameExpr$ | spath "message.auth_language" | search "message.auth_language"="$langPattern$" | spath "message.type" | search "message.type"="Authentication:start" | fields time message.auth_app_name message.auth_uuid message.sub message.sls_status message.sls_status_mesg message.sls_mbi_format_valid message.sls_mbi_format_synthetic message.sls_mbi_format_msg message.sls_mbi_hash message.sls_hicn_hash message.auth_pkce_method + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + + + + index=bluebutton source="/var/log/pyapps/perf_mon.log*" host=$bbEnv$ env=$bbEnvLabel$ $authAppNameExpr$ | spath "message.auth_language" | search "message.auth_language"="$langPattern$" | spath "message.type" | search "message.type"="fhir.server.authentication.match_fhir_id" | fields time message.auth_uuid message.fhir_id message.match_found message.hash_lookup_type message.auth_app_name message.hash_lookup_mesg message.mbi_hash message.hicn_hash message.auth_pkce_method + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + + + + index=bluebutton source="/var/log/pyapps/perf_mon.log*" host=$bbEnv$ env=$bbEnvLabel$ $authAppNameExpr$ | spath "message.auth_language" | search "message.auth_language"="$langPattern$" | spath "message.type" | search "message.type"="mymedicare_cb:get_and_update_user" | search "message.mesg"="CREATE beneficiary record" OR "message.mesg"="RETURN existing beneficiary record" | fields time message.auth_uuid message.crosswalk.fhir_id message.crosswalk.user_id_type message.hash_lookup_type message.auth_app_name message.mesg message.mbi_hash message.hicn_hash message.auth_pkce_method message.status + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + + + + index=bluebutton source="/var/log/pyapps/perf_mon.log*" host=$bbEnv$ env=$bbEnvLabel$ $authAppNameExpr$ | spath "message.auth_language" | search "message.auth_language"="$langPattern$" | spath "message.type" | search "message.type"="mymedicare_cb:get_and_update_user" | search "message.mesg"="RETURN existing beneficiary record" | fields time message.auth_uuid message.crosswalk.fhir_id message.crosswalk.user_id_type message.hash_lookup_type message.auth_app_name message.mesg message.mbi_hash message.hicn_hash message.auth_pkce_method message.status + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + + + + index=bluebutton source="/var/log/pyapps/perf_mon.log*" host=$bbEnv$ env=$bbEnvLabel$ $authAppNameExpr$ | spath "message.auth_language" | search "message.auth_language"="$langPattern$" | spath "message.type" | search "message.type"="mymedicare_cb:create_beneficiary_record" | fields time message.auth_uuid message.fhir_id message.username message.auth_app_name message.mesg mesg message.user_mbi_hash message.user_hicn_hash message.auth_pkce_method message.status + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + + + + index=bluebutton source="/var/log/pyapps/perf_mon.log*" host=$bbEnv$ env=$bbEnvLabel$ $authAppNameExpr$ | spath "message.auth_language" | search "message.auth_language"="$langPattern$" | spath "message.type" | search "message.type"="Authentication:success" | fields time message.auth_uuid message.auth_crosswalk_action message.sub message.user.crosswalk.fhir_id message.user.crosswalk.user_id_type message.auth_app_name message.user.crosswalk.user_mbi_hash message.user.crosswalk.user_hicn_hash message.auth_pkce_method + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + + + + index=bluebutton source="/var/log/pyapps/perf_mon.log*" host=$bbEnv$ env=$bbEnvLabel$ $authAppNameExpr$ | spath "message.auth_language" | search "message.auth_language"="$langPattern$" | spath "message.path" | search "message.path"="/mymedicare/sls-callback" | fields time message.auth_uuid message.ip_addr message.response_code message.auth_app_name message.auth_pkce_type message.location + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + + + + [\w-]+)/$" | search "message.location"="" | fields time message.auth_uuid message.ip_addr message.response_code message.user message.auth_app_name message.auth_pkce_method ]]> + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + + + + [\w-]+)/$" | search "message.location"!="" | fields time message.auth_uuid message.ip_addr message.response_code message.user message.auth_app_name message.auth_pkce_method message.location]]> + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + + + + index=bluebutton source="/var/log/pyapps/perf_mon.log*" host=$bbEnv$ env=$bbEnvLabel$ $authAppNameExpr$ | spath "message.auth_language" | search "message.auth_language"="$langPattern$" | spath "message.type" | search "message.type"="Authorization" | fields time message.auth_uuid message.auth_status message.message.application.name message.user.username message.user.crosswalk.fhir_id message.allow message.auth_share_demographic_scopes message.auth_require_demographic_scopes message.user.crosswalk.user_id_type message.auth_app_name message.user.crosswalk.user_mbi_hash message.user.crosswalk.user_hicn_hash message.auth_pkce_method message.scopes message.data_access_grant_delete_cnt message.access_token_delete_cnt message.refresh_token_delete_cnt message.auth_crosswalk_action + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + + + + index=bluebutton source="/var/log/pyapps/perf_mon.log*" host=$bbEnv$ env=$bbEnvLabel$ $authApplicationNameExpr$ | spath "message.auth_language" | search "message.auth_language"="$langPattern$" | spath "message.type" | search "message.type"="AccessToken" | search message.action="authorized" | fields time message.auth_uuid message.application.name message.crosswalk.fhir_id message.user.username message.auth_app_name message.auth_pkce_method message.access_token message.action message.auth_crosswalk_action message.auth_grant_type message.auth_require_demographic_scopes message.auth_share_demographic_scopes message.scopes message.req_qparam_lang + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + + + + index=bluebutton source="/var/log/pyapps/perf_mon.log*" host=$bbEnv$ env=$bbEnvLabel$ $authAppNameExpr$ | spath "message.req_qparam_lang" | search "message.path"="/v*/o/authorize/*" message.req_qparam_lang="es*" | fields time message.auth_uuid message.auth_app_name message.ip_addr message.response_code message.path message.auth_pkce_method message.req_qparam_lang + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + +
+
+ + + + + + impl + + + Test env=test + + + Sandbox env=impl + + + Prod env=prod + + + ALL env=* + + + prod + + + + + + + + ALL + + + ALL + + + Dev + + + Test + + + Sandbox + + + Prod + + + ALL + + + + + + + + + -60m@m + + + now + + + + + + + + + ALL + + + ALL + + + ALL + + + AppName + + + name + + + + index=bluebutton source="/var/log/pyapps/perf_mon.log*" env=$bbEnvLabel$ host=$bbEnv$ |spath output=name path="message.auth_app_name" | table name | dedup name | sort name + + + $t_local.earliest$ + + + $t_local.latest$ + + + + + + message.auth_app_name!="TestApp" AND message.auth_app_name!="new-relic" + + + message.application.name!="TestApp" AND message.application.name!="new-relic" + + + + + message.auth_app_name="$value$" + + + message.auth_app_name="$value$" + + + + + + + + + + V1+V2 + + + V1+V2 + + + V1 + + + V2 + + + V1+V2 + + + APIVersion + + + APIVersion + + + + + v* + + + v[12] + + + V1+V2 + + + + + v1 + + + v1 + + + V1 + + + + + v2 + + + v2 + + + V2 + + + + + + + + + + All + + + All + + + English + + + Spanish + + + All + + + LoginLanguage + + + LoginLanguage + + + + + * + + + .* + + + All + + + + + en-us + + + en-us + + + English + + + + + es-mx + + + es-mx + + + Spanish + + + + + + + + + + +

+ + Authorization Flow Logging Event Counts - Start to Completed + +

+ Event Ordering: +

+

+ + + + + + + + + + + + + + + + + + + + +
+ 1. Initial Authorization + + 2. Medicare.gov Login Redirect + + 3. Authentication Start + + 4. FHIR_ID Matched +
+ 5. Beneficiary User/Crosswalk Retreivals + + 6a. Existing Beneficiary found in BB2 User/Crosswalk Record + + 6b. New Beneficiary Created in BB2 User/Crosswalk Record + + 7. Authentication Success - SLS-to-FHIR_ID Matched + + 8. Medicare.gov SLS-Callback COMPLETE +
+ 9. Authorization ApprovalView + + 10. Authorization ApprovalView (redirect to bene consent form) + + 11. Beneficiary Authorized Application - via consent form + + 12. Authorized Application Receives Access Token +
+

+

+ + + + + + + + 1. Initial Authorization + + + + + + $result.count$ + + + + search "message.response_code"!="200" | stats count + + + + + + + + + + 2. Medicare.gov Login Redirect + + + + + stats count + + + + + + + + + + 3. Authentication Start + + + + + stats count + + + + + + + + + + 4. FHIR_ID Matched + + + + + stats count + + + + + + + + + + + + 5. Beneficiary User/Crosswalk Retreivals + + + + + stats count + + + + + + + + + + 6a. Existing Beneficiary record FOUND in BB2 User/Crosswalk + + + + + stats count + + + + + + + + + + 6b. New Beneficiary record CREATED in BB2 User/Crosswalk + + + + + stats count + + + + + + + + + + 7. Authentication Success - SLS-to-FHIR_ID Matched + + + + + stats count + + + + + + + + + + 8. Medicare.gov SLS-Callback COMPLETE + + + + + stats count + + + + + + + + + + + + 9. Authorization ApprovalView + + + + + stats count + + + + + + + + + + 10. Authorization ApprovalView (redirect to bene consent form) + + + + + stats count + + + + + + + + + + 11. Beneficiary Authorized Application - via consent form + + + + + stats count + + + + + + + + + + 12. Authorized Application Receives Token + + + + + + $result.count$ + + + + search message.auth_grant_type=authorization_code | stats count + + + + + + + + + + 13. Spanish Language Authorization + + + + + + $result.count$ + + + + stats count + + + + + + + + search?q=index%3Dbluebutton%20source%3D%22%2Fvar%2Flog%2Fpyapps%2Fperf_mon.log*%22%7C%20spath%20%22message.req_qparam_lang%22%20%7C%20search%20%22message.path%22%3D%22%2Fv*%2Fo%2Fauthorize%2F*%22%20message.req_qparam_lang%3D%22es*%22%20%7C%20fields%20time%20message.auth_uuid%20message.auth_app_name%20message.ip_addr%20message.response_code%20message.path%20message.auth_pkce_method%20message.req_qparam_lang%20%7C%20stats%20count&earliest=$t_local.earliest$&latest=$t_local.latest$ + + + + + + + + + + Initial Authorization Request / Authorization Completed % + + + + | makeresults | eval Total1=$tokEpCount$, Total2=$tokTcCount$ | eval percent= round((Total2/Total1)*100,1) | table percent + + + 1 + + + + + + + + + + + + + + + 1. Initial Authorization Request Events TIME-CHART + + + + timechart count + + + + + + + + + + + + + + + 12. Authorized Application Receives Token Events TIME-CHART + + + + search message.auth_grant_type=authorization_code | timechart count + + + + + + + + + + + + + + +

+ + 1. Initial Authorization Request Events: Events for the initial link given to the beneficiary to authorize an application by making a request to the /$apiVersionsPattern$/o/authorize/ end point. This is the start of the authorization flow. The built-in testclient events are excluded (response_code=200) + +

+
+ +
+
+ + + + TOTAL Events + + + + + + $result.count$ + + + + | makeresults | eval Total1=$tokEpCount$ | table Total1 + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + + + + + + + + + SUCCESSFUL Events (response_code == "302") + + + + + + $result.count$ + + + + stats count + + + + + + + + + + + SUCCESSFUL vs. TOTAL Percentage % + + + + | makeresults | eval Total1=$tokEpCount$, Total2=$tokInitOkCount$ | eval percent= round((Total2/Total1)*100,1) | table percent + + + 1 + + + + + + + + + + + + + + + Events by response_code + + + + stats count by message.response_code + + + + + + + + + + Events by PKCE method (MOBILE vs. WEB). + + + + eval pkce_method=if('message.auth_pkce_method'="S256","MOBILE","WEB") | stats count by pkce_method + + + + + + + + + + Events by Application + + + + stats count by message.auth_app_name + + + + + + + + + + + + + table time message.auth_uuid message.auth_app_name message.ip_addr message.response_code message.path message.auth_pkce_method + + + + + + + + + + +
+
+
+ + + + +

+ + 2. Medicare.gov Login Redirect Events: Events from the apps.mymedicare_cb.views.mymedicare_login() request used to redirect the beneficiary to the Medicare.gov login page + +

+
+ +
+
+ + + + TOTAL Events + + + + + + $result.count$ + + + + stats count + + + + + + + + + + SUCCESSFUL Events (response_code == "302") + + + + + + $result.count$ + + + + search "message.response_code"="302" | stats count + + + + + + + + + + + SUCCESSFUL vs. TOTAL Percentage % + + + + | makeresults | eval Total1=$tokMyMedTotalCount$, Total2=$tokMyMedOkCount$ | eval percent= round((Total2/Total1)*100,1) | table percent + + + 1 + + + + + + + + + + + + + + + Events by response_code + + + + stats count by message.response_code + + + + + + + + + + Events by PKCE method (MOBILE vs. WEB). + + + + eval pkce_method=if('message.auth_pkce_method'="S256","MOBILE","WEB") | stats count by pkce_method + + + + + + + + + + Events by Application + + + + stats count by message.auth_app_name + + + + + + + + + + + + + table time message.auth_uuid message.auth_app_name message.ip_addr message.auth_pkce_method message.response_code message.location + + + + + + + + + + +
+
+
+ + + + +

+ + 3. Authentication Start Events: After beneficiary Medicare.gov login. Events from the apps.mymedicare_cb.views.authenticate() function AFTER receiving a response from the SLS userinfo end point and BEFORE the beneficiary has been matched to a FHIR_ID with the BFD back end. + +

+
+ +
+
+ + + + TOTAL Events + + + + + + $result.count$ + + + + stats count + + + + + + + + + + SUCCESSFUL Events (sls_status == "OK") + + + + + + $result.count$ + + + + search message.sls_status="OK" | stats count + + + + + + + + + + + SUCCESSFUL vs. TOTAL Percentage % + + + + | makeresults | eval Total1=$tokStartTotalCount$, Total2=$tokStartOkCount$ | eval percent= round((Total2/Total1)*100,1) | table percent + + + 1 + + + + + + + + + + + + + + + Events with SLS MBI FORMAT VALID (true vs. false) + + + + stats count by message.sls_mbi_format_valid + + + + + + + + + + Events with SLS MBI FORMAT SYNTHETIC (true vs. false) + + + + stats count by message.sls_mbi_format_synthetic + + + + + + + + + + Events by sls_mbi_format_msg + + + + stats count by message.sls_mbi_format_msg + + + + + + + + + + + + Events by PKCE method (MOBILE vs. WEB). + + + + eval pkce_method=if('message.auth_pkce_method'="S256","MOBILE","WEB") | stats count by pkce_method + + + + + + + + + + Events by Application + + + + stats count by message.auth_app_name + + + + + + + + + + + + + table time message.auth_app_name message.auth_uuid message.sub message.sls_status message.sls_status_mesg message.sls_mbi_format_valid message.sls_mbi_format_synthetic message.sls_mbi_format_msg message.sls_mbi_hash message.sls_hicn_hash message.auth_pkce_method + + + + + + + + + + +
+
+
+ + + + +

+ + 4. FHIR_ID Matched Events: Events from the match_fhir_id() function used to match either MBI or HICN hash to a FHIR_ID via the BFD backend. + +

+
+ +
+
+ + + + TOTAL Events + + + + + + $result.count$ + + + + stats count + + + + + + + + + + SUCCESSFUL Events (match_found == "true") + + + + + + $result.count$ + + + + search "message.match_found"="true" | stats count + + + + + + + + + + + SUCCESSFUL vs. TOTAL Percentage % + + + + | makeresults | eval Total1=$tokFhirMatchTotalCount$, Total2=$tokFhirMatchOkCount$ | eval percent= round((Total2/Total1)*100,1) | table percent + + + 1 + + + + + + + + + + + + + + + Events by match_found + + + + search "message.match_found"="true" | stats count by message.match_found + + + + + + + + + + Events by hash_lookup_type + + + + search "message.match_found"="true" | stats count by message.hash_lookup_type + + + + + + + + + + Events by hash_lookup_mesg + + + + search "message.match_found"="true" | stats count by message.hash_lookup_mesg + + + + + + + + + + + + Events by PKCE method (MOBILE vs. WEB). + + + + search "message.match_found"="true" | eval pkce_method=if('message.auth_pkce_method'="S256","MOBILE","WEB") | stats count by pkce_method + + + + + + + + + + Events by Application + + + + search "message.match_found"="true" | stats count by message.auth_app_name + + + + + + + + + + + + + table time message.auth_uuid message.fhir_id message.match_found message.hash_lookup_type message.auth_app_name message.hash_lookup_mesg message.mbi_hash message.hicn_hash message.auth_pkce_method + + + + + + + + + + +
+
+
+ + + + +

+ + 5. Beneficiary User/Crosswalk Retreival Events: Events using the get_and_update_user() to FIND User/Crosswalk associated with the identity information from the ID provider (SLS). + +

+
+ +
+
+ + + + TOTAL Events + + + + + + $result.count$ + + + + stats count + + + + + + + + + + SUCCESSFUL Events (status="OK") + + + + + + $result.count$ + + + + search "message.status"="OK" | stats count + + + + + + + + + + + SUCCESSFUL vs. TOTAL Percentage % + + + + | makeresults | eval Total1=$tokGetUpdateTotalCount$, Total2=$tokGetUpdateOkCount$ | eval percent= round((Total2/Total1)*100,1) | table percent + + + 1 + + + + + + + + + + + + + + + Events by user_id_type (Previously stored crosswalk type) + + + + stats count by message.crosswalk.user_id_type + + + + + + + + + + Events by hash_lookup_type (type used to match FHIR_ID) + + + + stats count by message.hash_lookup_type + + + + + + + + + + Events by mesg + + + + stats count by message.mesg + + + + + + + + + + + + Events by PKCE method (MOBILE vs. WEB). + + + + eval pkce_method=if('message.auth_pkce_method'="S256","MOBILE","WEB") | stats count by pkce_method + + + + + + + + + + Events by Application + + + + stats count by message.auth_app_name + + + + + + + + + + + + + table time message.auth_uuid message.status message.crosswalk.fhir_id message.crosswalk.user_id_type message.hash_lookup_type message.auth_app_name message.mesg message.mbi_hash message.hicn_hash message.auth_pkce_method + + + + + + + + + + +
+
+
+ + + + +

+ + 6a. Existing Beneficiary record FOUND in User/Crosswalk Events: Events from the get_and_update_user() function that found and/or updated an existing User/Crosswalk entry. + +

+
+ +
+
+ + + + TOTAL Events + + + + + + $result.count$ + + + + stats count + + + + + + + + + + SUCCESSFUL Events (status="OK")) + + + + + + $result.count$ + + + + search "message.status"="OK" | stats count + + + + + + + + + + + SUCCESSFUL vs. TOTAL Percentage % + + + + | makeresults | eval Total1=$tokGetExistingTotalCount$, Total2=$tokGetExistingOkCount$ | eval percent= round((Total2/Total1)*100,1) | table percent + + + 1 + + + + + + + + + + + + + + + Events by user_id_type (BEFORE: Previously stored crosswalk type) + + + + stats count by message.crosswalk.user_id_type + + + + + + + + + + Events by hash_lookup_type (AFTER: type used to match FHIR_ID) + + + + stats count by message.hash_lookup_type + + + + + + + + + + Events by mesg + + + + stats count by message.mesg + + + + + + + + + + + + Events by PKCE method (MOBILE vs. WEB). + + + + eval pkce_method=if('message.auth_pkce_method'="S256","MOBILE","WEB") | stats count by pkce_method + + + + + + + + + + Events by Application + + + + stats count by message.auth_app_name + + + + + + + + + + + + + table time message.auth_uuid message.status message.crosswalk.fhir_id message.crosswalk.user_id_type message.hash_lookup_type message.auth_app_name message.mesg message.mbi_hash message.hicn_hash message.auth_pkce_method + + + + + + + + + + +
+
+
+ + + + +

+ + 6b. New Beneficiary User/Crosswalk Created Record Events: Events from the create_beneficiary_record() function used to create a new User/Crosswalk associated with the identity information from the ID provider (SLS). New records are created for a beneficiaries first matching with the BB2 system (for their first application). + +

+
+ +
+
+ + + + TOTAL Events + + + + + + $result.count$ + + + + stats count + + + + + + + + + + SUCCESSFUL Events (status="OK") + + + + + + $result.count$ + + + + search "message.status"="OK" | stats count + + + + + + + + + + + SUCCESSFUL vs. TOTAL Percentage % + + + + | makeresults | eval Total1=$tokCreateBeneTotalCount$, Total2=$tokCreateBeneOkCount$ | eval percent= round((Total2/Total1)*100,1) | table percent + + + 1 + + + + + + + + + + + + + + + Events by by message.mesg + + + + stats count by message.mesg + + + + + + + + + + Events by PKCE method (MOBILE vs. WEB). + + + + eval pkce_method=if('message.auth_pkce_method'="S256","MOBILE","WEB") | stats count by pkce_method + + + + + + + + + + Events by Application + + + + stats count by message.auth_app_name + + + + + + + + + + + + + table time message.auth_uuid message.status message.fhir_id message.username message.auth_app_name message.mesg mesg message.user_mbi_hash message.user_hicn_hash message.auth_pkce_method + + + + + + + + + + +
+
+
+ + + + +

+ + 7. Authentication Success - SLS-to-FHIR_ID Matched Events: Events from the apps.mymedicare_cb.views.authenticate() function AFTER the beneficiary has been successfully matched and a User/Crosswalk instance has been retreived or created. + +

+
+ +
+
+ + + + TOTAL Events + + + + + + $result.count$ + + + + stats count + + + + + + + + + + + Events by user_id_type (hash type used to match FHIR_ID) + + + + stats count by message.user.crosswalk.user_id_type + + + + + + + + + + Events by PKCE method (MOBILE vs. WEB). + + + + eval pkce_method=if('message.auth_pkce_method'="S256","MOBILE","WEB") | stats count by pkce_method + + + + + + + + + + + + Events by Crosswalk Action (R = Returning/Existing in BB2, C = Created/New to BB2). + + + + stats count by message.auth_crosswalk_action + + + + + + + + + + Events by Application + + + + stats count by message.auth_app_name + + + + + + + + + + + + + table time message.auth_uuid message.auth_crosswalk_action message.sub message.user.crosswalk.fhir_id message.user.crosswalk.user_id_type message.auth_app_name message.user.crosswalk.user_mbi_hash message.user.crosswalk.user_hicn_hash message.auth_pkce_method + + + + + + + + + + +
+
+
+ + + + +

+ + 8. Medicare.gov SLS-Callback COMPLETE Request Events: Events for calls to the apps.mymedicare_cb.views.callback() view at completion. To reach this part of the flow, the beneficiary successfully authenticated with SLS after logging in to the Medicare.gov site. PATH=/mymedicare/sls-callback + +

+
+ +
+
+ + + + TOTAL Events + + + + + + $result.count$ + + + + stats count + + + + + + + + + + SUCCESSFUL Events (response_code=302) + + + + + + $result.count$ + + + + search "message.response_code"="302" | stats count + + + + + + + + + + + SUCCESSFUL vs. TOTAL Percentage % + + + + | makeresults | eval Total1=$tokSlsCbTotalCount$, Total2=$tokSlsCbOkCount$ | eval percent= round((Total2/Total1)*100,1) | table percent + + + 1 + + + + + + + + + + + + + + + Events by response_code + + + + stats count by message.response_code + + + + + + + + + + Events by PKCE method (MOBILE vs. WEB). + + + + eval pkce_method=if('message.auth_pkce_method'="S256","MOBILE","WEB") | stats count by pkce_method + + + + + + + + + + Events by Application + + + + stats count by message.auth_app_name + + + + + + + + + + + + + table time message.auth_uuid message.ip_addr message.response_code message.auth_app_name message.auth_pkce_type message.location + + + + + + + + + + +
+
+
+ + + + +

+ + 9. Authorization ApprovalView Request Events: Events for calls to the apps.dot_ext.views.authorization.ApprovalView(). At this step the beneficiary is presented with the consent form web page. This can have multiple events when a beneficiary refreshes the consent page. + +

+
+ +
+
+ + + + TOTAL Events + + + + + + $result.count$ + + + + stats count + + + + + + + + + + SUCCESSFUL Events (response_code=200) + + + + + + $result.count$ + + + + search "message.response_code"="200" | stats count + + + + + + + + + + + SUCCESSFUL vs. TOTAL Percentage % + + + + | makeresults | eval Total1=$tokApprovalVaTotalCount$, Total2=$tokApprovalVaOkCount$ | eval percent= round((Total2/Total1)*100,1) | table percent + + + 1 + + + + + + + + + + + + + + + Events by response_code + + + + stats count by message.response_code + + + + + + + + + + Events by PKCE method (MOBILE vs. WEB). + + + + eval pkce_method=if('message.auth_pkce_method'="S256","MOBILE","WEB") | stats count by pkce_method + + + + + + + + + + Events by Application + + + + stats count by message.auth_app_name + + + + + + + + + + + + + table time message.auth_uuid message.ip_addr message.response_code message.user message.auth_app_name message.auth_pkce_method + + + + + + + + + + +
+
+
+ + + + +

+ + 10. Authorization ApprovalView (redirect to bene consent form) Request Events: Events for calls to the apps.dot_ext.views.authorization.ApprovalView(). + +

+
+ +
+
+ + + + TOTAL Events + + + + + + $result.count$ + + + + stats count + + + + + + + + + + SUCCESSFUL Events (response_code=302) + + + + + + $result.count$ + + + + search "message.response_code"="302" | stats count + + + + + + + + + + + SUCCESSFUL vs. TOTAL Percentage % + + + + | makeresults | eval Total1=$tokAuthVbTotalCount$, Total2=$tokAuthVbOkCount$ | eval percent= round((Total2/Total1)*100,1) | table percent + + + 1 + + + + + + + + + + + + + + + Events by response_code + + + + stats count by message.response_code + + + + + + + + + + Events by PKCE method (MOBILE vs. WEB). + + + + eval pkce_method=if('message.auth_pkce_method'="S256","MOBILE","WEB") | stats count by pkce_method + + + + + + + + + + Events by Application + + + + stats count by message.auth_app_name + + + + + + + + + + + + + table time message.auth_uuid message.ip_addr message.response_code message.user message.auth_app_name message.auth_pkce_method message.location + + + + + + + + + + +
+
+
+ + + + +

+ + 11. Beneficiary Authorized Application Events: Events from the apps.dot_ext.views.authorization.AuthorizationView.form_valid() method. A signal is sent to the beneficiary_authorized_application handler after the beneficiary has interacted with the consent form page. At this step the beneficiary has POSTed the consent form response to BB2. + +

+
+ +
+
+ + + + TOTAL Events + + + + + + $result.count$ + + + + stats count + + + + + + + + + + + Events by auth_status (OK/FAIL) + + + + stats count by message.auth_status + + + + + + + + + + Events by user_id_type (hash type used for FHIR_ID match) + + + + stats count by message.user.crosswalk.user_id_type + + + + + + + + + + + + Events by PKCE method (MOBILE vs. WEB). + + + + eval pkce_method=if('message.auth_pkce_method'="S256","MOBILE","WEB") | stats count by pkce_method + + + + + + + + + + Events by Application + + + + stats count by message.auth_app_name + + + + + + + + + + + Beneficiary ALLOW total + + + + + + $result.count$ + + + + search "message.allow"="true" | stats count + + + + + + + + + + Beneficiary DENY total + + + + + + $result.count$ + + + + search "message.allow"="false" | stats count + + + + + + + + + + + Events by Beneficiary Allow/Deny + + + + stats count by message.allow + + + + + + + + + + + Beneficiary SHARE_DEMOGRAPHIC_SCOPES = TRUE choice total + + + + + + $result.count$ + + + + search "message.allow"="True" | search "message.auth_share_demographic_scopes"="True" | stats count + + + + + + + + + + Beneficiary SHARE_DEMOGRAPHIC_SCOPES = FALSE choice total + + + + + + $result.count$ + + + + search "message.allow"="True" | search "message.auth_share_demographic_scopes"="False" | stats count + + + + + + + + + + + Events by Beneficiary SHARE_DEMOGRAPHIC_SCOPES + + + + search "message.allow"="True" | stats count by message.auth_share_demographic_scopes + + + + + + + + + + + + + table time message.auth_uuid message.auth_status message.message.application.name message.user.username message.user.crosswalk.fhir_id message.allow message.auth_share_demographic_scopes message.auth_require_demographic_scopes message.user.crosswalk.user_id_type message.auth_app_name message.user.crosswalk.user_mbi_hash message.user.crosswalk.user_hicn_hash message.auth_pkce_method message.scopes message.data_access_grant_delete_cnt message.access_token_delete_cnt message.refresh_token_delete_cnt + + + + + + + + + + +
+
+
+ + + + +

+ + 12. Authorized Application Receives Access Token Events: Events from the oauth2_provider.signals.app_authorized signal handler when a app_authorized signal is sent. This is the final step in the authorization flow. + +

+
+ +
+
+ + + + Authorized Application Receives Token TOTAL Events + + + + + | makeresults | eval Total1=$tokTcCount$ | table Total1 + + + + + + + + + + 1. Initial Authorization TOTAL Events + + + + + | makeresults | eval Total1=$tokEpCount$ | table Total1 + + + + + + + + + + + Initial Authorization Request / Authorization Completed % + + + + | makeresults | eval Total1=$tokEpCount$, Total2=$tokTcCount$ | eval percent= round((Total2/Total1)*100,1) | table percent + + + 1 + + + + + + + + + + + + + + + Events by PKCE method (MOBILE vs. WEB). + + + + search message.auth_grant_type=authorization_code | eval pkce_method=if('message.auth_pkce_method'="S256","MOBILE","WEB") | stats count by pkce_method + + + + + + + + + + Events by Application + + + + search message.auth_grant_type=authorization_code | stats count by message.auth_app_name + + + + + + + + + + + + Events by Crosswalk Action (R = Returning/Existing in BB2, C = Created/New to BB2). + + + + search message.auth_grant_type=authorization_code | stats count by message.auth_crosswalk_action + + + + + + + + + + + + + search message.auth_grant_type=authorization_code | table time message.auth_uuid message.application.name message.user.username message.auth_app_name message.auth_pkce_method message.access_token message.action message.auth_crosswalk_action message.auth_grant_type message.auth_require_demographic_scopes message.auth_share_demographic_scopes + + + + + + + + + + +
+
+
+ + + + +

+ + DEMOGRAPHIC SCOPES STATISTICS - By Beneficiary and Application Consent Page Choices + +

+
+ +
+
+ + + + +

+ + Beneficiary Consent Form ALLOW/DENY Choices + +

+
+ +
+
+ + + + +

+ + ALL - Beneficiary Consent Form ALLOW/DENY Choices + +

+
+ +
+
+ + + + ALLOW total + + + + + | makeresults | eval Total1=$tokAllowTotalCount$ | table Total1 + + + + + + + + + + + ALLOW by New vs. Returning Bene + + + + search message.allow="True" | stats count by message.auth_crosswalk_action + + + + + + + + + DENY total + + + + + | makeresults | eval Total1=$tokDenyTotalCount$ | table Total1 + + + + + + + + + + + DENY by New vs. Returning Bene + + + + search message.allow="False" | stats count by message.auth_crosswalk_action + + + + + + + + + + Percentage by Allow vs. Deny + + + + | makeresults | eval totalAllow=$tokAllowTotalCount$, totalDeny=$tokDenyTotalCount$ | table totalAllowDenyChoices totalDeny totalAllow | transpose header_field="totalAllowDenyChoices" column_name="AllowDenyChoice" + + + $t_local.earliest$ + + + $t_local.latest$ + + + 1 + + + + + + + + + + + +

+ + Application Requires Demographic - Beneficiary Consent Form ALLOW/DENY Choices + +

+
+ +
+
+ + + + Beneficiary ALLOW total + + + + + + $result.count$ + + + + search message.auth_require_demographic_scopes="True" | search "message.allow"="true" | stats count + + + + + + + + + + + ALLOW by New vs. Returning Bene + + + + search message.auth_require_demographic_scopes="True" | search "message.allow"="true" | stats count by message.auth_crosswalk_action + + + + + + + + + Beneficiary DENY total + + + + + + $result.count$ + + + + search message.auth_require_demographic_scopes="True" | search "message.allow"="false" | stats count + + + + + + + + + + + DENY by New vs. Returning Bene + + + + search message.auth_require_demographic_scopes="True" | search "message.allow"="false" | stats count by message.auth_crosswalk_action + + + + + + + + + + Events by Beneficiary Allow/Deny + + + + search message.auth_require_demographic_scopes="True" | stats count by message.allow + + + + + + + + + + + +

+ + Application DOES NOT Require Demographic - Beneficiary Consent Form ALLOW/DENY Choices + +

+
+ +
+
+ + + + Beneficiary ALLOW total + + + + + + $result.count$ + + + + search message.auth_require_demographic_scopes="False" | search "message.allow"="True" | stats count + + + + + + + + + + + ALLOW by New vs. Returning Bene + + + + search message.auth_require_demographic_scopes="False" | search "message.allow"="True" | stats count by message.auth_crosswalk_action + + + + + + + + + Beneficiary DENY total + + + + + + $result.count$ + + + + search message.auth_require_demographic_scopes="False" | search "message.allow"="False" | stats count + + + + + + + + + + + DENY by New vs. Returning Bene + + + + search message.auth_require_demographic_scopes="False" | search "message.allow"="False" | stats count by message.auth_crosswalk_action + + + + + + + + + + Events by Beneficiary Allow/Deny + + + + search message.auth_require_demographic_scopes="False" | stats count by message.allow + + + + + + + + + + + +

+ + Beneficiary Consent Form SHARE_DEMOGRAPHC Information Choices + +

+
+ +
+
+ + + + +

+ + Beneficiary Consent Form SHARE_DEMOGRAPHIC_SCOPES (True/False) Choices (NOTE: Only when Application require_demographic_scopes = "True") + +

+
+ +
+
+ + + + Beneficiary SHARE=True + + + + + search message.auth_share_demographic_scopes="True" | stats count + + + + + + + + + + + SHARE=True by New vs. Returning Bene + + + + search message.auth_share_demographic_scopes="True" | stats count by message.auth_crosswalk_action + + + + + + + + + Beneficiary SHARE=False + + + + + search message.auth_share_demographic_scopes="False" | stats count + + + + + + + + + + + SHARE=False by New vs. Returning Bene + + + + search message.auth_share_demographic_scopes="False" | stats count by message.auth_crosswalk_action + + + + + + + + + + + Total Events + + + + + search (message.auth_share_demographic_scopes="True" OR message.auth_share_demographic_scopes="False") | stats count + + + + + + + + + + + Percentage by SHARE_DEMOGRAPHIC_SCOPES (True/False) + + + + search (message.auth_share_demographic_scopes="True" OR message.auth_share_demographic_scopes="False") | stats count by message.auth_share_demographic_scopes + + + + + + + + + + + +

+ + Application Breakdown of Beneficiary NOT SHARING via Consent Form + +

+
+ +
+
+ + + + + + search message.auth_share_demographic_scopes="False" | stats count by "message.auth_app_name" | table message.auth_app_name count + + + + + + + + + + +
+
+
+ + + + +

+ + ALL UN-SUCCESSFUL TOKEN ENDPOINT STATS: For all /v*/o/token/ endpoint requests + +

+
+ +
+
+ + + + + Events by response_code + + + + index=bluebutton source="/var/log/pyapps/perf_mon.log*" host=$bbEnv$ env=$bbEnvLabel$ | spath "message.path" | search "message.path"="/v*/o/token/" | search message.response_code!=200 | stats count by message.response_code + + + + + + + + + + + + + index=bluebutton source="/var/log/pyapps/perf_mon.log*" host=$bbEnv$ env=$bbEnvLabel$ | spath "message.path" | search "message.path"="/v*/o/token/" | search message.response_code!=200 | stats count by message.req_grant_type message.response_code + + + + + + + + + + +
+
+
+ + + + +

+ + TOKEN REFRESH STATS: Events from applications requesting a new access token using the refresh_token. + +

+
+ +
+
+ + + + Token via authorized signal event TOTAL + + + + + search message.auth_grant_type=refresh_token | stats count + + + + + + + + + + + Events by Application + + + + search message.auth_grant_type=authorization_code | stats count by message.application.name + + + + + + + + + + + + Request Events TIME-CHART + + + + search message.auth_grant_type=refresh_token | timechart count + + + + + + + + + + + + + + + + search message.auth_grant_type=refresh_token | table time message.application.name message.crosswalk.fhir_id message.user.username message.access_token message.action message.auth_grant_type message.scopes + + + + + + + + + + +
+
+
+