Skip to content

Commit 26cce99

Browse files
committed
Add Metrics to Steam Auth
1 parent b3042ff commit 26cce99

File tree

2 files changed

+76
-12
lines changed

2 files changed

+76
-12
lines changed

CustomIdentityComponent/lambda/login_with_steam.py

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,16 @@
1111
import requests
1212
from aws_lambda_powertools import Tracer
1313
from aws_lambda_powertools import Logger
14+
from aws_lambda_powertools import Metrics
15+
from aws_lambda_powertools import single_metric
16+
from aws_lambda_powertools.metrics import MetricUnit
1417
from aws_lambda_powertools.utilities import parameters
1518
import time
1619

1720
tracer = Tracer()
1821
logger = Logger()
22+
metrics = Metrics()
23+
metrics.set_default_dimensions(function=os.environ['AWS_LAMBDA_FUNCTION_NAME'])
1924
config = Config(connect_timeout=2, read_timeout=2)
2025
dynamodb = boto3.resource('dynamodb', config=config)
2126

@@ -25,6 +30,20 @@
2530
# Steam Web Api key from Secrets manager, cached between requests for 15 minutes
2631
steam_web_api_secret_max_age = 15 * 60
2732

33+
def record_success_metric():
34+
metrics.add_metric(name="success", unit=MetricUnit.Count, value=1)
35+
36+
37+
def record_failure_metric(reason: str):
38+
with single_metric(
39+
name="failure",
40+
unit=MetricUnit.Count,
41+
value=1,
42+
default_dimensions=metrics.default_dimensions
43+
) as metric:
44+
metric.add_dimension(
45+
name="reason", value=reason)
46+
2847
# Creates a new user when there's no existing user for the Steam ID
2948
@tracer.capture_method
3049
def create_user(steam_id):
@@ -47,6 +66,8 @@ def create_user(steam_id):
4766
logger.info("User already exists")
4867
return None
4968

69+
metrics.add_metric(name="created_user", unit=MetricUnit.Count, value=1)
70+
5071
return user_id
5172

5273
@tracer.capture_method
@@ -99,7 +120,7 @@ def get_existing_user(steam_id):
99120
@tracer.capture_method
100121
def add_new_user_to_steam_table(user_id, steam_id):
101122
try:
102-
steam_id_user_table_name = os.getenv("STEAM_USER_TABLE");
123+
steam_id_user_table_name = os.getenv("STEAM_USER_TABLE")
103124
steam_id_user_table = dynamodb.Table(steam_id_user_table_name)
104125
steam_id_user_table.put_item(
105126
Item={
@@ -109,12 +130,14 @@ def add_new_user_to_steam_table(user_id, steam_id):
109130
return True
110131
except Exception as e:
111132
logger.info("Exception adding user to Steam ID table: ", e)
133+
134+
metrics.add_metric(name="new_steam_user", unit=MetricUnit.Count, value=1)
112135

113136
return False
114137

115138
def link_steam_id_to_existing_user(user_id, steam_id):
116139
try:
117-
user_table_name = os.getenv("USER_TABLE");
140+
user_table_name = os.getenv("USER_TABLE")
118141
user_table = dynamodb.Table(user_table_name)
119142
# Update existing user
120143
user_table.update_item(
@@ -130,6 +153,8 @@ def link_steam_id_to_existing_user(user_id, steam_id):
130153
return True
131154
except Exception as e:
132155
logger.info("Exception linking user to existing user: ", e)
156+
157+
metrics.add_metric(name="linked_user", unit=MetricUnit.Count, value=1)
133158

134159
return False
135160

@@ -143,9 +168,19 @@ def check_steam_token(token: str) -> str:
143168
params={'key': steam_web_api_key, 'appid': os.environ['STEAM_APP_ID'], 'ticket': token})
144169
elapsed_ms = round(((datetime.datetime.utcnow()-send_time).microseconds)/1000)
145170
logger.debug(f'Steam response', elapsed_ms=elapsed_ms, code=response.status_code, headers=response.headers, body=response.text)
171+
172+
with single_metric(
173+
name="duration",
174+
unit=MetricUnit.Milliseconds,
175+
value=elapsed_ms,
176+
default_dimensions=metrics.default_dimensions
177+
) as metric:
178+
metric.add_dimension(name="partner", value='Steam')
179+
metric.add_dimension(name="api", value='ISteamUserAuth/AuthenticateUserTicket/v1')
146180

147181
if response.status_code != 200:
148182
logger.error("Steam returned an error", response_code=response.status_code)
183+
record_failure_metric(f'Steam returned {response.status_code}')
149184
return None
150185

151186
response_body = response.json()
@@ -155,30 +190,44 @@ def check_steam_token(token: str) -> str:
155190
break
156191

157192
logger.info("Received 103, retrying after a delay")
193+
with single_metric(
194+
name="retry",
195+
unit=MetricUnit.Count,
196+
value=1,
197+
default_dimensions=metrics.default_dimensions
198+
) as metric:
199+
metric.add_dimension(name="partner", value='Steam')
200+
metric.add_dimension(name="api", value='ISteamUserAuth/AuthenticateUserTicket/v1')
158201
time.sleep(1)
159202

160203
response_dict = response_body.get('response', {}).get('params', {})
161204
if not 'result' in response_dict or response_dict['result'] != 'OK':
162-
logger.info("Result in not OK", result= response_dict['result'])
205+
result = response_dict['result']
206+
logger.info("Result in not OK", result=result)
207+
record_failure_metric(f'Steam result {result}')
163208
return None
164209

165210
if not 'steamid' in response_dict:
166211
logger.error("steamid missing", response=response_dict)
212+
record_failure_metric(f'steamid missing')
167213
return None
168214
steam_user_id = response_dict['steamid']
169215

170216
if 'vacbanned' in response_dict and response_dict['publisherbanned']:
171217
logger.info("User is VAC Banned", steam_user_id=steam_user_id)
218+
record_failure_metric(f'VAC Banned')
172219
return None
173220

174221
if 'publisherbanned' in response_dict and response_dict['publisherbanned']:
175-
logger.info("User is Published Banned", steam_user_id=steam_user_id)
222+
logger.info("User is Publisher Banned", steam_user_id=steam_user_id)
223+
record_failure_metric(f'Publisher Banned')
176224
return None
177225

178226
return steam_user_id
179227

180228

181229
# define a lambda function that returns a user_id
230+
@metrics.log_metrics
182231
@tracer.capture_lambda_handler
183232
def lambda_handler(event, context):
184233

@@ -200,10 +249,12 @@ def lambda_handler(event, context):
200249
if steam_user_id:
201250
logger.info("Received Steam user ID: ", steam_user_id=steam_user_id)
202251
else:
252+
# failure metrics handled by check_steam_token
203253
return generate_error('Error: Failed to validate Steam token')
204254

205255
except Exception as e:
206256
logger.error("exception in check_steam_token", error=e)
257+
record_failure_metric(f'exception in check_steam_token {e}')
207258
return generate_error('Error: Token validation error')
208259

209260
if steam_user_id != None:
@@ -214,6 +265,7 @@ def lambda_handler(event, context):
214265
existing_user_request_success, user_id = get_existing_user(steam_user_id)
215266
# If there was a problem getting existing user, abort as we don't want to create duplicate
216267
if existing_user_request_success is False:
268+
record_failure_metric(f'Failed the try getting existing user')
217269
return generate_error('Error: Failed the try getting existing user')
218270
else:
219271
success = True # Successfully tried getting existing user, might still be None (not found)
@@ -227,12 +279,14 @@ def lambda_handler(event, context):
227279
# Validate the auth_token
228280
decoded_backend_token = decrypt(query_params['auth_token'])
229281
if decoded_backend_token is None:
282+
record_failure_metric(f'Failed to authenticate with existing identity')
230283
return generate_error('Error: Failed to authenticate with existing identity')
231284
# Set the user_id
232285
user_id = decoded_backend_token['sub']
233286
# Try to link the new user to an existing user
234287
success = link_steam_id_to_existing_user(user_id, steam_user_id)
235288
if success is False:
289+
record_failure_metric(f'Failed to link new user to existing user')
236290
return generate_error('Error: Failed to link new user to existing user')
237291

238292
# OPTION 3: Else If no user yet and we didn't request linking to an existing user, create one and add to user table
@@ -244,6 +298,7 @@ def lambda_handler(event, context):
244298
user_id = create_user(steam_user_id)
245299
tries += 1
246300
if user_id == None:
301+
record_failure_metric(f'Failed to create user')
247302
return generate_error('Error: Failed to create user')
248303

249304
# Add user to Appe Id User table in both cases (linking and new user)
@@ -257,7 +312,9 @@ def lambda_handler(event, context):
257312
# Create for scope "authenticated" so backend can differentiate from guest users if needed
258313
auth_token, refresh_token, auth_token_expires_in, refresh_token_expires_in = encrypt(payload, "authenticated")
259314
# NOTE: We might want to send back all attached identities from user table?
315+
record_success_metric()
260316
return generate_success(user_id, steam_user_id, auth_token, refresh_token, auth_token_expires_in, refresh_token_expires_in)
261317

262318
# Failed to return success, return final error
319+
record_failure_metric(f'Invalid request')
263320
return generate_error('Error: Failed to authenticate')

CustomIdentityComponent/lib/custom_identity_component-stack.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ export class CustomIdentityComponentStack extends Stack {
114114
environment: {
115115
"ISSUER_BUCKET": issuer_bucket.bucketName,
116116
"ISSUER_ENDPOINT": "https://"+distribution.domainName,
117-
"POWERTOOLS_SERVICE_NAME": "CustomIdentityComponentApi",
117+
"POWERTOOLS_METRICS_NAMESPACE": "AWS Game Tech",
118+
"POWERTOOLS_SERVICE_NAME": "CustomIdentityComponent",
118119
"SECRET_KEY_ID": secret.secretName,
119120
}
120121
});
@@ -210,7 +211,7 @@ export class CustomIdentityComponentStack extends Stack {
210211
// Define an API Gateway for the authentication component public endpoint
211212
const logGroup = new logs.LogGroup(this, "CustomIdentityAPiAccessLogs");
212213
const api_gateway = new apigw.RestApi(this, 'ApiGateway', {
213-
restApiName: 'CustomIdentityComponentApi',
214+
restApiName: 'CustomIdentityComponent',
214215
description: 'Custom Identity Component API',
215216
deployOptions: {
216217
accessLogDestination: new apigw.LogGroupLogDestination(logGroup),
@@ -268,7 +269,8 @@ export class CustomIdentityComponentStack extends Stack {
268269
memorySize: 2048,
269270
environment: {
270271
"ISSUER_URL": "https://"+distribution.domainName,
271-
"POWERTOOLS_SERVICE_NAME": "CustomIdentityComponentApi",
272+
"POWERTOOLS_METRICS_NAMESPACE": "AWS Game Tech",
273+
"POWERTOOLS_SERVICE_NAME": "CustomIdentityComponent",
272274
"SECRET_KEY_ID": secret.secretName,
273275
"USER_TABLE": user_table.tableName
274276
}
@@ -315,7 +317,8 @@ export class CustomIdentityComponentStack extends Stack {
315317
memorySize: 2048,
316318
environment: {
317319
"ISSUER_URL": "https://"+distribution.domainName,
318-
"POWERTOOLS_SERVICE_NAME": "CustomIdentityComponentApi",
320+
"POWERTOOLS_METRICS_NAMESPACE": "AWS Game Tech",
321+
"POWERTOOLS_SERVICE_NAME": "CustomIdentityComponent",
319322
"SECRET_KEY_ID": secret.secretName,
320323
"USER_TABLE": user_table.tableName
321324
}
@@ -396,7 +399,8 @@ export class CustomIdentityComponentStack extends Stack {
396399
memorySize: 2048,
397400
environment: {
398401
"ISSUER_URL": "https://"+distribution.domainName,
399-
"POWERTOOLS_SERVICE_NAME": "CustomIdentityComponentApi",
402+
"POWERTOOLS_METRICS_NAMESPACE": "AWS Game Tech",
403+
"POWERTOOLS_SERVICE_NAME": "CustomIdentityComponent",
400404
"SECRET_KEY_ID": secret.secretName,
401405
"USER_TABLE": user_table.tableName,
402406
"APPLE_APP_ID": appId,
@@ -457,7 +461,8 @@ export class CustomIdentityComponentStack extends Stack {
457461
memorySize: 2048,
458462
environment: {
459463
"ISSUER_URL": "https://"+distribution.domainName,
460-
"POWERTOOLS_SERVICE_NAME": "CustomIdentityComponentApi",
464+
"POWERTOOLS_METRICS_NAMESPACE": "AWS Game Tech",
465+
"POWERTOOLS_SERVICE_NAME": "CustomIdentityComponent",
461466
"SECRET_KEY_ID": privateKeySecret.secretName,
462467
"USER_TABLE": user_table.tableName,
463468
"STEAM_APP_ID": appId,
@@ -528,7 +533,8 @@ export class CustomIdentityComponentStack extends Stack {
528533
memorySize: 2048,
529534
environment: {
530535
"ISSUER_URL": "https://"+distribution.domainName,
531-
"POWERTOOLS_SERVICE_NAME": "CustomIdentityComponentApi",
536+
"POWERTOOLS_METRICS_NAMESPACE": "AWS Game Tech",
537+
"POWERTOOLS_SERVICE_NAME": "CustomIdentityComponent",
532538
"SECRET_KEY_ID": privateKeySecret.secretName,
533539
"USER_TABLE": user_table.tableName,
534540
"GOOGLE_PLAY_CLIENT_ID": googlePlayClientId,
@@ -598,7 +604,8 @@ export class CustomIdentityComponentStack extends Stack {
598604
memorySize: 2048,
599605
environment: {
600606
"ISSUER_URL": "https://"+distribution.domainName,
601-
"POWERTOOLS_SERVICE_NAME": "CustomIdentityComponentApi",
607+
"POWERTOOLS_METRICS_NAMESPACE": "AWS Game Tech",
608+
"POWERTOOLS_SERVICE_NAME": "CustomIdentityComponent",
602609
"SECRET_KEY_ID": secret.secretName,
603610
"USER_TABLE": user_table.tableName,
604611
"FACEBOOK_APP_ID" : appId,

0 commit comments

Comments
 (0)