Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
firefox-merge-…
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time
executable file 98 lines (86 sloc) 3.31 KB
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import Shared
import SwiftyJSON
private let log = Logger.browserLogger
public typealias IdentifierString = String
public extension IdentifierString {
func validate() -> Bool {
// Regex located here: http://gecko.readthedocs.io/en/latest/toolkit/components/telemetry/telemetry/collection/events.html#limits
let regex = try! NSRegularExpression(pattern: "^[a-zA-Z][a-zA-Z0-9_.]*[a-zA-Z0-9]$", options: [])
return regex.matches(in: self, options: [], range: NSRange(location: 0, length: self.count)).count > 0
}
}
// Telemetry Events
// Documentation: http://gecko.readthedocs.io/en/latest/toolkit/components/telemetry/telemetry/collection/events.html#events
public struct Event {
let timestamp: Timestamp
let category: IdentifierString
let method: IdentifierString
let object: IdentifierString
let value: String?
let extra: [String: String]?
public init(category: IdentifierString,
method: IdentifierString,
object: IdentifierString,
value: String? = nil,
extra: [String: String]? = nil) {
self.init(timestamp: .uptimeInMilliseconds(),
category: category,
method: method,
object: object,
value: value,
extra: extra)
}
init(timestamp: Timestamp,
category: IdentifierString,
method: IdentifierString,
object: IdentifierString,
value: String? = nil,
extra: [String: String]? = nil) {
self.timestamp = timestamp
self.category = category
self.method = method
self.object = object
self.value = value
self.extra = extra
}
public func validate() -> Bool {
let results = [category, method, object].map { $0.validate() }
// Fold down the results into false if any of the results is false.
return results.reduce(true) { $0 ? $1 :$0 }
}
public func pickle() -> Data? {
do {
return try JSONSerialization.data(withJSONObject: toArray(), options: [])
} catch let error {
log.error("Error pickling telemetry event. Error: \(error), Event: \(self)")
return nil
}
}
public static func unpickle(_ data: Data) -> Event? {
do {
let array = try JSONSerialization.jsonObject(with: data, options: []) as! [Any]
return Event(
timestamp: Timestamp(array[0] as! UInt64),
category: array[1] as! String,
method: array[2] as! String,
object: array[3] as! String,
value: array[4] as? String,
extra: array[5] as? [String: String]
)
} catch let error {
log.error("Error unpickling telemetry event: \(error)")
return nil
}
}
public func toArray() -> [Any] {
return [timestamp, category, method, object, value ?? NSNull(), extra ?? NSNull()]
}
}
extension Event: CustomDebugStringConvertible {
public var debugDescription: String {
return toArray().description
}
}