Network logs are automatically collected by Luciq when possible. There are many way to configure and manipulate these logs from the code.
Note: The maximum number of network logs sent with each report is 100.
Disable and Enable Request Logging
By default, request logging is enabled. It can be disabled using the API to the right.
NetworkLogger.enabled = false
LCQNetworkLogger.enabled = NO;
Omitting Requests from Logs
You can omit requests from being logged based on either their request or response details. [Luciq setNetworkLoggingRequestFilterPredicate:responseFilterPredicate:] allows you to specify two predicates that are going to be evaluated against every request and response to determine if the request should be included in logs or not.
The example code to the right will exclude all requests made to URLs that have /products path. It will also exclude all responses that has a success and redirection status code, thus only including requests with 4xx and 5xx responses.
requestFilterPredicate is evaluated against an NSURLRequest, while responseFilterPredicate is evaluated against an NSHTTPURLResponse.
let path = "/products"
let requestPredicate = NSPredicate(format: "URL.path MATCHES %@", path)
let responsePredicate = NSPredicate(format: "statusCode >= %d AND statusCode <= %d", 200, 399)
NetworkLogger.setNetworkLoggingRequestFilterPredicate(requestPredicate, responseFilterPredicate: responsePredicate)
NSString *path = @"/products";
NSPredicate *requestPredicate = [NSPredicate predicateWithFormat:@"URL.path MATCHES %@", path];
NSPredicate *responsePredicate = [NSPredicate predicateWithFormat:@"statusCode >= %d AND statusCode <= %d", 200, 399];
[LCQNetworkLogger setNetworkLoggingRequestFilterPredicate:requestPredicate responseFilterPredicate:responsePredicate];
Manual Network Logging
Manual network logging gives you precise control over what data is sent to Luciq. It's ideal for advanced scenarios like instrumenting a highly custom networking layer, or for selective logging in performance-sensitive apps where you only want to capture specific, high-importance requests.
You can log network requests manually using the following API:
NetworkLogger.addNetworkLog(
withUrl: "https://api.example.com/user",
method: "POST",
requestBody: requestBodyAsString,
requestBodySize: 1024, // in bytes
responseBody: responseBodyAsString,
responseBodySize: 1024, // in bytes
responseCode: 200,
requestHeaders: ["example":"example"],
responseHeaders: ["example":"example"],
contentType: "application/json",
errorDomain: nil, // If available when a request fails, otherwise `nil`
errorCode: 422, // If available when a request fails, otherwise 0
startTime: 1664625600000000, // Unix timestamp in microseconds
duration: 500000, // Duration in microseconds
gqlQueryName: "query", // If available, otherwise `nil`
serverErrorMessage: "error") // If available when request is gql, otherwise `nil`
[LCQNetworkLogger addNetworkLogWithUrl: @"https://api.example.com/user"
method: @"POST"
requestBody: requesteBodyAsString
requestBodySize: 1024 // in bytes
responseBody: responseBodyAsString
responseBodySize: 1024 // in bytes
responseCode: 200
requestHeaders: @{@"example": @"example"}
responseHeaders: @{@"example":@"example"}
contentType: @"application/json"
errorDomain: nil // If available when a request fails, otherwise `nil`
errorCode: 422 // If available when a request fails, otherwise 0
startTime: 1664625600000000 // Unix timestamp in microseconds
duration: 500000 // Duration in microseconds
gqlQueryName: @"query" // If available, otherwise `nil`
serverErrorMessage: @"error"]; // If available when request is gql, otherwise `nil`
Important: Timestamp Format
To ensure your network data is processed correctly, all time-based values (startTime, duration) must be passed in microseconds (µs), not milliseconds. Providing values in milliseconds will cause the requests to be dropped or processed incorrectly.
Obfuscating Data
Both requests and responses can be obfuscated if required. You can obfuscate user sensitive data in requests, like authentication tokens for example, without filtering out the whole request. As with requests, the response object, as well as the response data, could be modified for obfuscation purposes before they are logged.
Obfuscate Request
NetworkLogger.setRequestObfuscationHandler { (request) -> URLRequest in
var myRequest:NSMutableURLRequest = request as! NSMutableURLRequest
let urlString = request.url?.absoluteString
urlString = obfuscateAuthenticationTokenInString()
let obfuscatedURL = URL(string: urlString)
myRequest.url = obfuscatedURL
return myRequest.copy() as! URLRequest
}
LCQNetworkLogger.requestObfuscationHandler = ^NSURLRequest * _Nonnull(NSURLRequest * _Nonnull request) {
NSMutableURLRequest *myRequest = [request mutableCopy];
NSString *urlString = request.URL.absoluteString;
urlString = [self obfuscateAuthenticationTokenInString:urlString];
NSURL *obfuscatedURL = [NSURL URLWithString:urlString];
myRequest.URL = obfuscatedURL;
return myRequest;
};
NetworkLogger.setResponseObfuscationHandler { (data, response, completion) in
if let data = data {
let modifiedData = self.modify(data: data)
let modifiedResponse = self.modify(response: response)
completion(modifiedData, modifiedResponse)
}
}
[LCQNetworkLogger setResponseObfuscationHandler:^(NSData * _Nullable responseData, NSURLResponse * _Nonnull response, NetworkObfuscationCompletionBlock _Nonnull returnBlock) {
NSData *modifiedData = [self obfuscateData:responseData];
NSURLResponse *modifiedResponse = [self obfuscateResponse:response];
returnBlock(modifiedData, modifiedResponse);
}];
Requests Not Appearing
If your network requests aren't being logged automatically because you're probably using a custom NSURLSession or NSURLSessionConfiguration, you would need to enable logging for your NSURLSession using this API.
let configuration = URLSessionConfiguration.ephemeral
NetworkLogger.enableLogging(for: configuration)
let session = URLSession(configuration: configuration)
NSURLSessionConfiguration *configuration = NSURLSessionConfiguration.ephemeralSessionConfiguration;
[LCQNetworkLogger enableLoggingForURLSessionConfiguration:configuration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
If the requests still aren't appearing
You'll need to make sure that
enableLoggingForURLSessionConfiguration:was called just before using the configuration to create the session.
AFNetworking
To enable logging for AFNetworking, you may create this class, then use LCQAFURLSessionManager to create your requests.
// LCQAFURLSessionManager.h
#import <AFNetworking/AFNetworking.h>
@interface LCQAFURLSessionManager : AFURLSessionManager
@end
// LCQAFURLSessionManager.m
#import "LCQAFURLSessionManager.h"
#import <Luciq/Luciq.h>
@implementation LCQAFURLSessionManager
- (instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)configuration {
[LCQNetworkLogger enableLoggingForURLSessionConfiguration:configuration];
return [super initWithSessionConfiguration:configuration];
}
@end
Alamofire
To enable logging for Alamofire, you may create this class, then use LCQSessionManager to create your requests.
import Alamofire
import Luciq
class LCQSessionManager: Alamofire.Session {
static let sharedManager: LCQSessionManager = {
let configuration = URLSessionConfiguration.default
NetworkLogger.enableLogging(for: configuration)
let manager = LCQSessionManager(configuration: configuration)
return manager
}()
}
