@@ -33,6 +33,7 @@ class ApilyticsSender:
3333 method=request.method,
3434 request_size=len(request.body),
3535 user_agent=request.headers.get("user-agent"),
36+ ip=request.headers.get("x-forwarded-for", "").split(",")[0].strip(),
3637 ) as sender:
3738 response = get_response(request)
3839 sender.set_response_info(
@@ -56,6 +57,7 @@ def __init__(
5657 query : Optional [str ] = None ,
5758 request_size : Optional [int ] = None ,
5859 user_agent : Optional [str ] = None ,
60+ ip : Optional [str ] = None ,
5961 apilytics_integration : Optional [str ] = None ,
6062 integrated_library : Optional [str ] = None ,
6163 ) -> None :
@@ -70,6 +72,9 @@ def __init__(
7072 An empty string and None are treated equally. Can have an optional "?" at the start.
7173 request_size: Size of the user's HTTP request's body in bytes.
7274 user_agent: Value of the `User-Agent` header from the user's HTTP request.
75+ An empty string and None are treated equally.
76+ ip: User's IP address (used for geolocation, never stored nor sent to 3rd parties).
77+ An empty string and None are treated equally.
7378 apilytics_integration: Name of the Apilytics integration that's calling this,
7479 e.g. "apilytics-python-django". No need to pass this when calling from user code.
7580 integrated_library: Name and version of the integration that this is used in,
@@ -81,6 +86,7 @@ def __init__(
8186 self ._query = query
8287 self ._request_size = request_size
8388 self ._user_agent = user_agent
89+ self ._ip = ip
8490
8591 self ._response_size : Optional [int ] = None
8692 self ._status_code : Optional [int ] = None
@@ -147,6 +153,7 @@ def _send_metrics(self) -> None:
147153 # Don't send empty strings.
148154 ** ({"query" : self ._query } if self ._query else {}),
149155 ** ({"userAgent" : self ._user_agent } if self ._user_agent else {}),
156+ ** ({"ip" : self ._ip } if self ._ip else {}),
150157 ** (
151158 {"statusCode" : self ._status_code }
152159 if self ._status_code is not None
0 commit comments