Skip to content

Commit

Permalink
Add more diagnostics tools
Browse files Browse the repository at this point in the history
  • Loading branch information
alin23 committed Apr 19, 2019
1 parent c54a14d commit 6dd63f8
Show file tree
Hide file tree
Showing 24 changed files with 333 additions and 87 deletions.
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,7 @@ Releases/Lunar-2.3.3.dmg filter=lfs diff=lfs merge=lfs -text
Releases/Lunar-latest.dmg filter=lfs diff=lfs merge=lfs -text
Releases/Lunar2.3.3-2.3.1.delta filter=lfs diff=lfs merge=lfs -text
Releases/Lunar2.3.3-2.3.2.delta filter=lfs diff=lfs merge=lfs -text
Releases/Lunar-2.4.0.dmg filter=lfs diff=lfs merge=lfs -text
Releases/Lunar2.4.0-2.3.1.delta filter=lfs diff=lfs merge=lfs -text
Releases/Lunar2.4.0-2.3.2.delta filter=lfs diff=lfs merge=lfs -text
Releases/Lunar2.4.0-2.3.3.delta filter=lfs diff=lfs merge=lfs -text
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ Lunar/Generated/
.env.sh
Frameworks/*.framework*
.gitsecret/keys/random_seed
Lunar/Resources/dsa_priv.pem
Lunar/Resources/dsa_priv.pem
GoogleService-Info.plist
1 change: 1 addition & 0 deletions .gitsecret/paths/mapping.cfg
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.env.sh:4fa64b9b29471e1e73dbd99721e6cdda9efd2b753a01df1f1057ecf17f22c3f7
Lunar/Resources/dsa_priv.pem:4724e8ee0055cf3ddc55ca528691955d68879ec8abaafd3200cdfa20298ea1d9
GoogleService-Info.plist:3ed09415ccaa9634fb35e69d2915540a10a51a0c84f500cd75c42f6982e02a9d
20 changes: 10 additions & 10 deletions EDIDReader/EDIDReader/Logger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,23 @@
import Foundation

class Logger {
class func verbose(_ message: Any) {
print("VERBOSE: \(message)")
class func verbose(_ message: Any, context: Any? = nil) {
print("VERBOSE: \(message) (context \(String(describing: context)))")
}

class func debug(_ message: Any) {
print("DEBUG: \(message)")
class func debug(_ message: Any, context: Any? = nil) {
print("DEBUG: \(message) (context \(String(describing: context)))")
}

class func info(_ message: Any) {
print("INFO: \(message)")
class func info(_ message: Any, context: Any? = nil) {
print("INFO: \(message) (context \(String(describing: context)))")
}

class func warning(_ message: Any) {
print("WARNING: \(message)")
class func warning(_ message: Any, context: Any? = nil) {
print("WARNING: \(message) (context \(String(describing: context)))")
}

class func error(_ message: Any) {
print("ERROR: \(message)")
class func error(_ message: Any, context: Any? = nil) {
print("ERROR: \(message) (context \(String(describing: context)))")
}
}
Binary file added GoogleService-Info.plist.secret
Binary file not shown.
4 changes: 2 additions & 2 deletions Lunar.dmg
Git LFS file not shown
4 changes: 2 additions & 2 deletions Lunar.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
/* Begin PBXContainerItemProxy section */
C7151939224E335A0024C6F6 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = C7151935224E33590024C6F6 /* EDIDReader.xcodeproj */;
containerPortal = C7151935224E33590024C6F6 /* Project object */;
proxyType = 2;
remoteGlobalIDString = C715192B224E33590024C6F6;
remoteInfo = EDIDReader;
Expand Down Expand Up @@ -295,7 +295,7 @@
C7151936224E33590024C6F6 /* Products */ = {
isa = PBXGroup;
children = (
C715193A224E335A0024C6F6 /* EDIDReader */,
C715193A224E335A0024C6F6,
);
name = Products;
sourceTree = "<group>";
Expand Down
144 changes: 127 additions & 17 deletions Lunar/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
// Copyright © 2017 Alin. All rights reserved.
//

import Alamofire
import Carbon.HIToolbox
import Cocoa
import Compression
import CoreLocation
import Crashlytics
import Fabric
Expand All @@ -24,6 +26,14 @@ extension Collection where Index: Comparable {
}

let TEST_MODE = false
let LOG_URL = FileManager().urls(for: .cachesDirectory, in: .userDomainMask).first!.appendingPathComponent(appName, isDirectory: true).appendingPathComponent("swiftybeaver.log", isDirectory: false)
let TRANSFER_URL = "https://transfer.sh"
let DEBUG_DATA_HEADERS: HTTPHeaders = [
"Content-type": "application/octet-stream",
"Max-Downloads": "2",
"Max-Days": "5",
]
let LOG_ENCODING_THRESHOLD: UInt64 = 100_000_000 // 100MB

var lunarDisplayNames = [
"Moony",
Expand Down Expand Up @@ -83,15 +93,15 @@ class AppDelegate: NSObject, NSApplicationDelegate, CLLocationManagerDelegate, N
var noonObserver: NSKeyValueObservation?
var brightnessOffsetObserver: NSKeyValueObservation?
var contrastOffsetObserver: NSKeyValueObservation?
var loginItemObserver: NSKeyValueObservation?
var adaptiveModeObserver: NSKeyValueObservation?
var hotkeyObserver: NSKeyValueObservation?
var loginItemObserver: NSKeyValueObservation?

@IBOutlet var menu: NSMenu!
@IBOutlet var preferencesMenuItem: NSMenuItem!
@IBOutlet var stateMenuItem: NSMenuItem!
@IBOutlet var toggleMenuItem: NSMenuItem!
@IBOutlet var loginMenuItem: NSMenuItem!
@IBOutlet var debugMenuItem: NSMenuItem!

@IBOutlet var percent0MenuItem: NSMenuItem!
@IBOutlet var percent25MenuItem: NSMenuItem!
Expand Down Expand Up @@ -169,23 +179,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, CLLocationManagerDelegate, N
}
}

func setLoginMenuItemState(state: Bool) {
if state {
loginMenuItem?.state = .on
} else {
loginMenuItem?.state = .off
}
}

func handleDaemon() {
let runningApps = NSWorkspace.shared.runningApplications
let isRunning = runningApps.contains(where: { app in app.bundleIdentifier == launcherAppId })

SMLoginItemSetEnabled(launcherAppId as CFString, datastore.defaults.startAtLogin)
setLoginMenuItemState(state: datastore.defaults.startAtLogin)
loginItemObserver = datastore.defaults.observe(\.startAtLogin, options: [.new], changeHandler: { _, change in
SMLoginItemSetEnabled(launcherAppId as CFString, change.newValue ?? false)
self.setLoginMenuItemState(state: change.newValue ?? false)
})

if isRunning {
Expand Down Expand Up @@ -358,7 +358,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, CLLocationManagerDelegate, N

func applicationDidFinishLaunching(_: Notification) {
UserDefaults.standard.register(defaults: ["NSApplicationCrashOnExceptions": true])
Fabric.with([Crashlytics.start(withAPIKey: secrets.fabricApiKey)])
Fabric.with([Crashlytics.self, Answers.self])
log.initLogger()
handleDaemon()
startReceivingSignificantLocationChanges()
Expand All @@ -382,6 +382,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, CLLocationManagerDelegate, N
func applicationWillTerminate(_: Notification) {
log.info("Going down")
datastore.save()
datastore.defaults.set(false, forKey: "debug")
activity.invalidate()
}

Expand Down Expand Up @@ -553,10 +554,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, CLLocationManagerDelegate, N
brightnessAdapter.toggle()
}

@IBAction func toggleStartAtLogin(sender _: Any?) {
datastore.defaults.set(!datastore.defaults.startAtLogin, forKey: "startAtLogin")
}

@IBAction func showWindow(sender _: Any?) {
showWindow()
}
Expand All @@ -568,4 +565,117 @@ class AppDelegate: NSObject, NSApplicationDelegate, CLLocationManagerDelegate, N
@IBAction func leaveFeedback(_: Any) {
NSWorkspace.shared.open(URL(string: "mailto:[email protected]?Subject=Let%27s%20talk%20about%20Lunar%21")!)
}

func failDebugData() {
if dialog(message: "There's no debug data stored for Lunar", info: "Do you want to send a message to the developer?") {
NSWorkspace.shared.open(URL(string: "mailto:[email protected]?Subject=Let%27s%20talk%20about%20Lunar%21")!)
}
}

@IBAction func sendDebugData(_: Any) {
guard dialog(message: "This will run a few diagnostic tests by trying to change the brightness and contrast of all of your external displays", info: "Do you want to continue?") else {
return
}

let oldTitle = debugMenuItem.title
debugMenuItem.isEnabled = false
debugMenuItem.title = "Diagnosing displays"

datastore.defaults.set(true, forKey: "debug")
let oldBrightness = [CGDirectDisplayID: NSNumber](uniqueKeysWithValues: brightnessAdapter.displays.map { ($0, $1.brightness) })
let oldContrast = [CGDirectDisplayID: NSNumber](uniqueKeysWithValues: brightnessAdapter.displays.map { ($0, $1.contrast) })

brightnessAdapter.resetDisplayList()
for (id, display) in brightnessAdapter.displays {
for value in 1...100 {
display.brightness = NSNumber(value: value)
display.contrast = NSNumber(value: value)
}
if let brightness = oldBrightness[id] {
for value in stride(from: 100, through: brightness.intValue, by: -1) {
display.brightness = NSNumber(value: value)
}
}
if let contrast = oldContrast[id] {
for value in stride(from: 100, through: contrast.intValue, by: -1) {
display.contrast = NSNumber(value: value)
}
}
}

datastore.defaults.set(false, forKey: "debug")

debugMenuItem.title = "Gathering logs"
guard let sourceString = FileManager().contents(atPath: LOG_URL.path) else {
failDebugData()
return
}

let destinationBuffer = UnsafeMutablePointer<UInt8>.allocate(capacity: sourceString.count)
let sourceBuffer = sourceString.map { $0 }
let algorithm = COMPRESSION_LZMA

debugMenuItem.title = "Compressing logs"
let compressedSize = compression_encode_buffer(
destinationBuffer, sourceString.count,
sourceBuffer, sourceString.count,
nil,
algorithm
)

var debugData = sourceString
var mimeType = "text/plain"
var fileName = "lunar.log"
if compressedSize > 0 {
let encodedFileURL = LOG_URL.appendingPathExtension("lzma")

FileManager.default.createFile(
atPath: encodedFileURL.path,
contents: nil,
attributes: nil
)

debugData = NSData(
bytesNoCopy: destinationBuffer,
length: compressedSize
) as Data
mimeType = "application/x-lzma"
fileName = "lunar.log.lzma"
}

debugMenuItem.title = "Compressing logs"
Alamofire.upload(debugData, to: "\(TRANSFER_URL)/\(fileName)", method: .put, headers: DEBUG_DATA_HEADERS).validate(statusCode: 200 ..< 300).responseString(completionHandler: {
response in
defer {
self.debugMenuItem.title = oldTitle
self.debugMenuItem.isEnabled = true
}
log.info("Got response from transfer.sh", context: response.response)
if let err = response.error {
log.error("Debug data upload response error: \(err)")
self.failDebugData()
return
}

guard let url = response.value, !url.isEmpty,
let urlEncoded = url.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
let subject = "Lunar logs: \(url)".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) else {
log.error("Debug data upload response empty")
self.failDebugData()
return
}
log.info("Uploaded logs to \(url)")
NSWorkspace.shared.open(URL(string: "mailto:[email protected]?subject=\(subject)&body=\(urlEncoded)")!)
})
}

func dialog(message: String, info: String) -> Bool {
let alert = NSAlert()
alert.messageText = message
alert.informativeText = info
alert.alertStyle = .warning
alert.addButton(withTitle: "OK")
alert.addButton(withTitle: "Cancel")
return alert.runModal() == .alertFirstButtonReturn
}
}
22 changes: 18 additions & 4 deletions Lunar/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,14 @@
<attributedString key="attributedTitle"/>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleStartAtLoginWithSender:" target="Voe-Tx-rLC" id="UeX-aW-1MF"/>
<binding destination="3YV-ka-Eop" name="value" keyPath="values.startAtLogin" id="em1-5W-zou"/>
</connections>
</menuItem>
<menuItem title="Debug Mode" id="8wq-Qw-uJg">
<attributedString key="attributedTitle"/>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<binding destination="3YV-ka-Eop" name="value" keyPath="values.debug" id="q17-cG-lR6"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" title="Intensity" id="hyT-YG-TrU"/>
Expand Down Expand Up @@ -118,6 +125,12 @@
<action selector="leaveFeedback:" target="Voe-Tx-rLC" id="p7H-ng-T89"/>
</connections>
</menuItem>
<menuItem title="Open Lunar diagnostics" id="kSD-gy-XkR">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="sendDebugData:" target="Voe-Tx-rLC" id="Cm0-Xt-xz2"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="GNT-HB-tbd"/>
<menuItem title="Check for updates..." id="Gfc-g2-RLO">
<modifierMask key="keyEquivalentModifierMask"/>
Expand All @@ -136,7 +149,7 @@
</menuItem>
</items>
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="Qnj-0T-tfY"/>
<outlet property="delegate" destination="Voe-Tx-rLC" id="aL5-qs-Cgt"/>
</connections>
</menu>
</menuItem>
Expand Down Expand Up @@ -183,7 +196,7 @@
<outlet property="brightnessUpMenuItem" destination="jpb-NA-VFf" id="vA0-By-Vrr"/>
<outlet property="contrastDownMenuItem" destination="0mO-FB-Bx4" id="xyG-dc-x6a"/>
<outlet property="contrastUpMenuItem" destination="VlH-nA-RFU" id="PmV-aD-CdY"/>
<outlet property="loginMenuItem" destination="HeU-1X-veM" id="T04-59-iC5"/>
<outlet property="debugMenuItem" destination="kSD-gy-XkR" id="NKJ-Lt-QFN"/>
<outlet property="menu" destination="uQy-DD-JDr" id="Vtf-ap-8J3"/>
<outlet property="percent0MenuItem" destination="9Jm-7d-C6T" id="f9t-jn-RIA"/>
<outlet property="percent100MenuItem" destination="UL7-qh-pTF" id="9lg-G5-OdX"/>
Expand All @@ -198,6 +211,7 @@
<customObject id="JCY-9H-EwC" customClass="SUUpdater"/>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
<userDefaultsController id="3YV-ka-Eop"/>
</objects>
<point key="canvasLocation" x="75" y="0.0"/>
</scene>
Expand All @@ -209,7 +223,7 @@
<window key="window" title="Settings" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" titlebarAppearsTransparent="YES" titleVisibility="hidden" id="IQv-IB-iLA" customClass="ModernWindow" customModule="Lunar" customModuleProvider="target">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" fullSizeContentView="YES"/>
<rect key="contentRect" x="561" y="239" width="750" height="500"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1050"/>
<value key="minSize" type="size" width="750" height="500"/>
<value key="maxSize" type="size" width="750" height="500"/>
<userDefinedRuntimeAttributes>
Expand Down
6 changes: 1 addition & 5 deletions Lunar/BrightnessAdapter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,7 @@ class BrightnessAdapter {
static func logDisplays(_ displays: [Display]) {
for (i, display) in displays.enumerated() {
Crashlytics.sharedInstance().setObjectValue(display.serial, forKey: "display\(i)")
for (j, str) in DDC.getTextDescriptors(displayID: display.id).enumerated() {
Crashlytics.sharedInstance().setObjectValue(str, forKey: "display\(i)-descriptor\(j)")
log.debug("display\(i)-descriptor\(j): \(str)")
}
Answers.logCustomEvent(withName: "Found Display", customAttributes: ["serial": display.serial])
Answers.logCustomEvent(withName: "Found Display", customAttributes: ["serial": display.serial, "name": display.name])
}
}

Expand Down
Loading

0 comments on commit 6dd63f8

Please sign in to comment.