@@ -56,6 +56,8 @@ def __init__(self, auth_url=AUTH_URL, auth_headers=AUTH_HEADERS):
5656 self .auth_headers = auth_headers
5757 self .token = None
5858 self .token_expiry = None
59+ logger .info (f"Initializing AuthManager with URL: { auth_url } " )
60+ logger .info (f"Auth headers (excluding credentials): { dict (filter (lambda x : x [0 ] != 'Authorization' , auth_headers .items ()))} " )
5961
6062 def get_token (self ):
6163 """Get a valid authentication token, refreshing if necessary."""
@@ -68,9 +70,15 @@ def get_token(self):
6870 if response .status == 200 :
6971 response_data = json .load (response )
7072 self .token = response_data .get ("Token" )
73+ if not self .token :
74+ logger .error ("No token in response data" )
75+ logger .error (f"Response data: { response_data } " )
76+ raise Exception ("No token in response data" )
7177 self .token_expiry = current_time + timedelta (minutes = 55 )
7278 logger .info ("Authentication token successfully refreshed" )
79+ logger .debug (f"Token expiry set to: { self .token_expiry } " )
7380 else :
81+ logger .error (f"Failed to obtain access token. Status: { response .status } " )
7482 raise Exception (f"Failed to obtain access token: { response .status } " )
7583 except HTTPError as e :
7684 logger .error (f"HTTP Error while obtaining access token: { e .code } - { e .reason } " )
@@ -144,6 +152,9 @@ def fetch_ap_data(auth_manager, rounded_unix_timestamp, retries=3):
144152 i = 0
145153 length = 250 # Initial value to enter the loop
146154
155+ logger .info (f"Starting AP data fetch with timestamp: { rounded_unix_timestamp } " )
156+ logger .info (f"Using site ID: { KEELE_CAMPUS_SITE_ID } " )
157+
147158 while length == 250 : # Continue until we get less than 250 devices (pagination)
148159 params = {
149160 "deviceRole" : "AP" ,
@@ -160,36 +171,63 @@ def fetch_ap_data(auth_manager, rounded_unix_timestamp, retries=3):
160171 attempt = 0
161172 while attempt < retries :
162173 try :
174+ logger .info (f"Making API request { i + 1 } with params: { params } " )
163175 with urlopen (req , context = ssl_context , timeout = 60 ) as response :
164176 device_info = json .load (response )
177+ logger .info (f"API Response for request { i + 1 } : { json .dumps (device_info , indent = 2 )} " )
178+
179+ # Log response statistics
180+ response_data = device_info .get ("response" , [])
181+ logger .info (f"Response { i + 1 } contains { len (response_data )} devices" )
182+ if response_data :
183+ sample_device = response_data [0 ]
184+ logger .info (f"Sample device data: { json .dumps (sample_device , indent = 2 )} " )
185+
165186 break # Exit retry loop if successful
166187 except (HTTPError , URLError ) as e :
167188 attempt += 1
168- logger .warning (f"{ type (e ).__name__ } (attempt { attempt } ): { e } " )
189+ logger .warning (f"{ type (e ).__name__ } (attempt { attempt } / { retries } ): { e } " )
169190 if attempt < retries :
170- time .sleep (2 ** attempt ) # Exponential backoff
191+ wait_time = 2 ** attempt
192+ logger .info (f"Waiting { wait_time } seconds before retry..." )
193+ time .sleep (wait_time ) # Exponential backoff
171194 else :
172195 logger .error (f"Failed due to { type (e ).__name__ } after { retries } attempts: { e } " )
173196 raise
174197 except Exception as e :
175198 attempt += 1
176- logger .warning (f"General error (attempt { attempt } ): { e } " )
199+ logger .warning (f"General error (attempt { attempt } / { retries } ): { e } " )
177200 if attempt < retries :
178- time .sleep (2 ** attempt )
201+ wait_time = 2 ** attempt
202+ logger .info (f"Waiting { wait_time } seconds before retry..." )
203+ time .sleep (wait_time )
179204 else :
180205 logger .error (f"Failed due to general error after { retries } attempts: { e } " )
181206 raise
182207
183- response_length = len (device_info [ "response" ] )
208+ response_length = len (device_info . get ( "response" , []) )
184209 length = response_length # Update length for loop condition
185- data .extend (device_info [ "response" ] )
210+ data .extend (device_info . get ( "response" , []) )
186211
187212 i += 1
188213 if response_length == 250 : # If we got the maximum number, there might be more
214+ logger .info ("Received maximum number of devices, checking for more..." )
189215 time .sleep (2 ) # Avoid API rate limits
190216
191217 # Remove duplicates by uuid
192218 unique_devices = list ({device ["uuid" ]: device for device in data }.values ())
219+ logger .info (f"Total devices before deduplication: { len (data )} " )
220+ logger .info (f"Total unique devices after deduplication: { len (unique_devices )} " )
221+
222+ if len (unique_devices ) == 0 :
223+ logger .warning ("No APs found in the API response. This might indicate an issue with the API parameters or authentication." )
224+ logger .warning (f"API URL: { DEVICE_HEALTH_URL } " )
225+ logger .warning (f"Site ID: { KEELE_CAMPUS_SITE_ID } " )
226+ logger .warning (f"Timestamp: { rounded_unix_timestamp } " )
227+ else :
228+ logger .info ("Successfully fetched AP data" )
229+ logger .info (f"First device sample: { json .dumps (unique_devices [0 ], indent = 2 )} " )
230+
193231 return unique_devices
194232
195233def get_ap_data (auth_manager = None , retries = 3 ):
@@ -254,13 +292,22 @@ def insert_apclientcount_data(device_info_list, timestamp, session=None):
254292 radioId_map = {r .radioname : r .radioid for r in session .query (RadioType ).all ()}
255293 for device in device_info_list :
256294 ap_name = device ['name' ]
257- location = device .get ('location' , '' )
258- location_parts = location .split ('/' )
259- if len (location_parts ) < 5 :
260- logger .warning (f"Skipping device { ap_name } due to invalid location format: { location } " )
295+ # Try to get location from multiple fields
296+ location = device .get ('location' )
297+ if not location or len (location .split ('/' )) < 5 :
298+ snmp_location = device .get ('snmpLocation' )
299+ if snmp_location and snmp_location .lower () != 'default location' and snmp_location .strip ():
300+ location = snmp_location
301+ else :
302+ location_name = device .get ('locationName' )
303+ if location_name and location_name .strip ().lower () != 'null' :
304+ location = location_name
305+ location_parts = location .split ('/' ) if location else []
306+ if len (location_parts ) < 2 :
307+ logger .warning (f"Skipping device { ap_name } due to missing or invalid location fields. location: { location } " )
261308 continue
262- building_name = location_parts [3 ]
263- floor_name = location_parts [4 ]
309+ building_name = location_parts [- 2 ] if len ( location_parts ) >= 2 else 'Unknown'
310+ floor_name = location_parts [- 1 ] if len ( location_parts ) >= 1 else 'Unknown'
264311 # Building
265312 building = session .query (ApBuilding ).filter_by (buildingname = building_name ).first ()
266313 if not building :
0 commit comments