Logging changes

- Adds `Logging` protocol
- Moves to Swift-style `OSLog` usage

os_log to Logger

os_log audit

Replacment of os.log with Logging
This commit is contained in:
Stuart Breckenridge
2022-08-03 15:37:12 +08:00
parent bff3c26490
commit 0dd4689bf0
52 changed files with 270 additions and 271 deletions

View File

@@ -9,6 +9,7 @@
import Foundation
import Account
import Secrets
import RSCore
public enum ArticleExtractorState {
case ready
@@ -23,7 +24,7 @@ protocol ArticleExtractorDelegate {
func articleExtractionDidComplete(extractedArticle: ExtractedArticle)
}
class ArticleExtractor {
class ArticleExtractor: Logging {
private var dataTask: URLSessionDataTask? = nil
@@ -91,6 +92,7 @@ class ArticleExtractor {
}
}
} catch {
self.logger.error("Failed to extract article: \(error.localizedDescription, privacy: .public)")
self.state = .failedToParse
DispatchQueue.main.async {
self.delegate?.articleExtractionDidFail(with: error)

View File

@@ -8,8 +8,9 @@
import Foundation
import Zip
import RSCore
public class ArticleThemeDownloader {
public class ArticleThemeDownloader: Logging {
public enum ArticleThemeDownloaderError: LocalizedError {
case noThemeFile
@@ -63,6 +64,7 @@ public class ArticleThemeDownloader {
}
return URL(fileURLWithPath: unzipDirectory.appendingPathComponent(themeFilePath!).path)
} catch {
logger.error("Failed to unzip theme: \(error.localizedDescription, privacy: .public)")
try? FileManager.default.removeItem(at: location)
throw error
}
@@ -101,7 +103,7 @@ public class ArticleThemeDownloader {
try FileManager.default.removeItem(atPath: downloadDirectory().appendingPathComponent(path).path)
}
} catch {
print(error)
logger.error("Failed to clean up theme download: \(error.localizedDescription, privacy: .public)")
}
}
}

View File

@@ -14,7 +14,7 @@ public extension Notification.Name {
static let CurrentArticleThemeDidChangeNotification = Notification.Name("CurrentArticleThemeDidChangeNotification")
}
final class ArticleThemesManager: NSObject, NSFilePresenter {
final class ArticleThemesManager: NSObject, NSFilePresenter, Logging {
static var shared: ArticleThemesManager!
public let folderPath: String
@@ -58,6 +58,7 @@ final class ArticleThemesManager: NSObject, NSFilePresenter {
do {
try FileManager.default.createDirectory(atPath: folderPath, withIntermediateDirectories: true, attributes: nil)
} catch {
logger.error("Could not create folder for themes: \(error.localizedDescription, privacy: .public)")
assertionFailure("Could not create folder for Themes.")
abort()
}
@@ -113,6 +114,7 @@ final class ArticleThemesManager: NSObject, NSFilePresenter {
return try ArticleTheme(path: path, isAppTheme: isAppTheme)
} catch {
NotificationCenter.default.post(name: .didFailToImportThemeWithError, object: nil, userInfo: ["error": error])
logger.error("Failed to import theme: \(error.localizedDescription, privacy: .public)")
return nil
}

View File

@@ -7,12 +7,10 @@
//
import Foundation
import os.log
import RSWeb
import RSCore
struct CacheCleaner {
static let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CacheCleaner")
struct CacheCleaner: Logging {
static func purgeIfNecessary() {
@@ -35,10 +33,10 @@ struct CacheCleaner {
for tempItem in [faviconsFolderURL, imagesFolderURL, feedURLToIconURL, homePageToIconURL, homePagesWithNoIconURL] {
do {
os_log(.info, log: self.log, "Removing cache file: %@", tempItem.absoluteString)
CacheCleaner.logger.info("Removing cache file: \(tempItem.absoluteString, privacy: .public)")
try FileManager.default.removeItem(at: tempItem)
} catch {
os_log(.error, log: self.log, "Could not delete cache file: %@", error.localizedDescription)
CacheCleaner.logger.error("Could not delete cache file: \(error.localizedDescription, privacy: .public)")
}
}

View File

@@ -18,7 +18,7 @@ extension Notification.Name {
static let FaviconDidBecomeAvailable = Notification.Name("FaviconDidBecomeAvailableNotification") // userInfo key: FaviconDownloader.UserInfoKey.faviconURL
}
final class FaviconDownloader {
final class FaviconDownloader: Logging {
private static let saveQueue = CoalescingQueue(name: "Cache Save Queue", interval: 1.0)
@@ -297,6 +297,7 @@ private extension FaviconDownloader {
let data = try encoder.encode(homePageToFaviconURLCache)
try data.write(to: url)
} catch {
logger.error("Failed to Save Home Page To Favicon URL Cache: \(error.localizedDescription, privacy: .public)")
assertionFailure(error.localizedDescription)
}
}
@@ -311,6 +312,7 @@ private extension FaviconDownloader {
let data = try encoder.encode(Array(homePageURLsWithNoFaviconURLCache))
try data.write(to: url)
} catch {
logger.error("Failed to Save URLs With No Favicon URL Cache: \(error.localizedDescription, privacy: .public)")
assertionFailure(error.localizedDescription)
}
}

View File

@@ -7,7 +7,6 @@
//
import Foundation
import os.log
import RSCore
import RSWeb
@@ -19,7 +18,7 @@ extension Notification.Name {
static let DidLoadFavicon = Notification.Name("DidLoadFaviconNotification")
}
final class SingleFaviconDownloader {
final class SingleFaviconDownloader: Logging {
enum DiskStatus {
case unknown, notOnDisk, onDisk
@@ -29,8 +28,6 @@ final class SingleFaviconDownloader {
var iconImage: IconImage?
let homePageURL: String?
private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "SingleFaviconDownloader")
private var lastDownloadAttemptDate: Date
private var diskStatus = DiskStatus.unknown
private var diskCache: BinaryDiskCache
@@ -128,7 +125,9 @@ private extension SingleFaviconDownloader {
self.diskStatus = .onDisk
}
}
catch {}
catch {
self.logger.error("Unable to save to disk: \(error.localizedDescription, privacy: .public)")
}
}
}
@@ -139,16 +138,16 @@ private extension SingleFaviconDownloader {
return
}
downloadUsingCache(url) { (data, response, error) in
downloadUsingCache(url) { [weak self] (data, response, error) in
if let data = data, !data.isEmpty, let response = response, response.statusIsOK, error == nil {
self.saveToDisk(data)
self?.saveToDisk(data)
RSImage.image(with: data, imageResultBlock: completion)
return
}
if let error = error {
os_log(.info, log: self.log, "Error downloading image at %@: %@.", url.absoluteString, error.localizedDescription)
self?.logger.error("Error downloading image at: \(url.absoluteString, privacy: .sensitive): \(error.localizedDescription, privacy: .public)")
}
completion(nil)

View File

@@ -7,7 +7,6 @@
//
import Foundation
import os.log
import RSCore
import RSWeb
@@ -16,9 +15,7 @@ extension Notification.Name {
static let ImageDidBecomeAvailable = Notification.Name("ImageDidBecomeAvailableNotification") // UserInfoKey.url
}
final class ImageDownloader {
private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "ImageDownloader")
final class ImageDownloader: Logging {
private let folder: String
private var diskCache: BinaryDiskCache
@@ -103,19 +100,19 @@ private extension ImageDownloader {
return
}
downloadUsingCache(imageURL) { (data, response, error) in
downloadUsingCache(imageURL) { [weak self] (data, response, error) in
if let data = data, !data.isEmpty, let response = response, response.statusIsOK, error == nil {
self.saveToDisk(url, data)
self?.saveToDisk(url, data)
completion(data)
return
}
if let response = response as? HTTPURLResponse, response.statusCode >= HTTPResponseCode.badRequest && response.statusCode <= HTTPResponseCode.notAcceptable {
self.badURLs.insert(url)
self?.badURLs.insert(url)
}
if let error = error {
os_log(.info, log: self.log, "Error downloading image at %@: %@.", url, error.localizedDescription)
self?.logger.error("Error downloading image at: \(url, privacy: .sensitive): \(error.localizedDescription, privacy: .public)")
}
completion(nil)

View File

@@ -7,15 +7,12 @@
//
import Foundation
import os.log
import RSCore
import RSParser
import Account
final class ExtensionContainersFile {
final class ExtensionContainersFile: Logging {
private static var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "extensionContainersFile")
private static var filePath: String = {
let appGroup = Bundle.main.object(forInfoDictionaryKey: "AppGroup") as! String
let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup)
@@ -55,7 +52,7 @@ final class ExtensionContainersFile {
})
if let error = errorPointer?.pointee {
os_log(.error, log: log, "Read from disk coordination failed: %@.", error.localizedDescription)
logger.error("Read from coordination failed: \(error.localizedDescription, privacy: .public)")
}
return extensionContainers
@@ -88,19 +85,19 @@ private extension ExtensionContainersFile {
let fileCoordinator = NSFileCoordinator()
let fileURL = URL(fileURLWithPath: ExtensionContainersFile.filePath)
fileCoordinator.coordinate(writingItemAt: fileURL, options: [], error: errorPointer, byAccessor: { writeURL in
fileCoordinator.coordinate(writingItemAt: fileURL, options: [], error: errorPointer, byAccessor: { [weak self] writeURL in
do {
let extensionAccounts = AccountManager.shared.sortedActiveAccounts.map { ExtensionAccount(account: $0) }
let extensionContainers = ExtensionContainers(accounts: extensionAccounts)
let data = try encoder.encode(extensionContainers)
try data.write(to: writeURL)
} catch let error as NSError {
os_log(.error, log: Self.log, "Save to disk failed: %@.", error.localizedDescription)
self?.logger.error("Save to disk failed: \(error.localizedDescription, privacy: .public)")
}
})
if let error = errorPointer?.pointee {
os_log(.error, log: Self.log, "Save to disk coordination failed: %@.", error.localizedDescription)
logger.error("Save to disk coordination failed: \(error.localizedDescription, privacy: .public)")
}
}

View File

@@ -7,13 +7,11 @@
//
import Foundation
import os.log
import Account
import RSCore
final class ExtensionFeedAddRequestFile: NSObject, NSFilePresenter {
final class ExtensionFeedAddRequestFile: NSObject, NSFilePresenter, Logging {
private static var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "extensionFeedAddRequestFile")
private static var filePath: String = {
let appGroup = Bundle.main.object(forInfoDictionaryKey: "AppGroup") as! String
let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup)
@@ -82,12 +80,12 @@ final class ExtensionFeedAddRequestFile: NSObject, NSFilePresenter {
try data.write(to: url)
} catch let error as NSError {
os_log(.error, log: Self.log, "Save to disk failed: %@.", error.localizedDescription)
logger.error("Save to disk failed: \(error.localizedDescription, privacy: .public)")
}
})
if let error = errorPointer?.pointee {
os_log(.error, log: Self.log, "Save to disk coordination failed: %@.", error.localizedDescription)
logger.error("Save to disk coordination failed: \(error.localizedDescription, privacy: .public)")
}
}
@@ -107,7 +105,7 @@ private extension ExtensionFeedAddRequestFile {
var requests: [ExtensionFeedAddRequest]? = nil
fileCoordinator.coordinate(writingItemAt: fileURL, options: [.forMerging], error: errorPointer, byAccessor: { url in
fileCoordinator.coordinate(writingItemAt: fileURL, options: [.forMerging], error: errorPointer, byAccessor: { [weak self] url in
do {
if let fileData = try? Data(contentsOf: url),
@@ -119,12 +117,12 @@ private extension ExtensionFeedAddRequestFile {
try data.write(to: url)
} catch let error as NSError {
os_log(.error, log: Self.log, "Save to disk failed: %@.", error.localizedDescription)
self?.logger.error("Save to disk failed: \(error.localizedDescription, privacy: .public)")
}
})
if let error = errorPointer?.pointee {
os_log(.error, log: Self.log, "Save to disk coordination failed: %@.", error.localizedDescription)
logger.error("Save to disk coordination failed: \(error.localizedDescription, privacy: .public)")
}
requests?.forEach { processRequest($0) }

View File

@@ -7,10 +7,11 @@
//
import Foundation
import RSCore
struct WidgetDataDecoder {
struct WidgetDataDecoder: Logging {
static func decodeWidgetData() throws -> WidgetData {
func decodeWidgetData() throws -> WidgetData {
let appGroup = Bundle.main.object(forInfoDictionaryKey: "AppGroup") as! String
let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup)
let dataURL = containerURL?.appendingPathComponent("widget-data.json")
@@ -22,13 +23,14 @@ struct WidgetDataDecoder {
}
}
static func sampleData() -> WidgetData {
func sampleData() -> WidgetData {
let pathToSample = Bundle.main.url(forResource: "widget-sample", withExtension: "json")
do {
let data = try Data(contentsOf: pathToSample!)
let decoded = try JSONDecoder().decode(WidgetData.self, from: data)
return decoded
} catch {
logger.error("Error accessing sample widget data: \(error.localizedDescription, privacy: .public)")
return WidgetData(currentUnreadCount: 0, currentTodayCount: 0, currentStarredCount: 0, unreadArticles: [], starredArticles: [], todayArticles: [], lastUpdateTime: Date())
}
}

View File

@@ -8,16 +8,15 @@
import Foundation
import WidgetKit
import os.log
import UIKit
import RSCore
import Articles
import Account
public final class WidgetDataEncoder {
public final class WidgetDataEncoder: Logging {
private let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "Application")
private let fetchLimit = 7
private var backgroundTaskID: UIBackgroundTaskIdentifier!
@@ -36,7 +35,7 @@ public final class WidgetDataEncoder {
@available(iOS 14, *)
func encodeWidgetData() throws {
flushSharedContainer()
os_log(.debug, log: log, "Starting encoding widget data.")
logger.debug("Started encoding widget data.")
do {
let unreadArticles = Array(try AccountManager.shared.fetchArticles(.unread(fetchLimit))).sortedByDate(.orderedDescending)
@@ -95,14 +94,14 @@ public final class WidgetDataEncoder {
}
let encodedData = try? JSONEncoder().encode(latestData)
os_log(.debug, log: self.log, "Finished encoding widget data.")
self.logger.debug("Finished encoding widget data.")
if self.fileExists() {
try? FileManager.default.removeItem(at: self.dataURL!)
os_log(.debug, log: self.log, "Removed widget data from container.")
self.logger.debug("Removed widget data from container.")
}
if FileManager.default.createFile(atPath: self.dataURL!.path, contents: encodedData, attributes: nil) {
os_log(.debug, log: self.log, "Wrote widget data to container.")
self.logger.debug("Wrote widget data to container.")
WidgetCenter.shared.reloadAllTimelines()
UIApplication.shared.endBackgroundTask(self.backgroundTaskID!)
self.backgroundTaskID = .invalid