2. Phone Home is...
A system to collect client-side errors
● Client
○ JavaScript
○ Runs in user’s browser
● Server
○ Scalatra
○ Accepts POST data from clients, saves to
MongoDB
https://github.com/cb372/phone-home
http://phone-home-demo.herokuapp.com/
3. Motivation
● Wanted to debug weird, unreproducable
jQuery errors affecting a handful of users
○ IE, of course
● Kept system running long-term to track
number and types of JS errors
● Page load timing info also useful
5. Client - Features
● Error handling
○ Using either wrap() or window.onerror
● Collect page load timing info
○ Supported browsers: FF, Chrome, IE9+
● Basic logging support
○ Send arbitrary log messages to PH server
● Sampling rate
○ Avoid overloading PH server
● Custom field support
○ Attach custom key-value metadata to errors
6. Server - Features
● Accepts POST data from clients
○ Writes to LTSV log file
○ Stores to MongoDB
● Simple admin UI
○ Stats
○ Recent events list
● Client sample page
○ Useful for testing that POSTs are working
● CORS support (details later)
● Async event processing
○ Respond to clients as quickly as possible
8. CORS - XHR
Situation:
Website and PH are on separate domains
(www.foo.com and ph.foo.com)
Problem:
Browser will not let you send an XHR to
another domain, for security reasons
Solution:
PhoneHome server supports CORS
10. CORS - XHR
Situation:
Website and PH are on separate domains
(www.foo.com and ph.foo.com)
Problem:
IE (< 10) doesn’t support CORS for XHR
(IE 8, 9 offer limited support using XDomainRequest)
Solution:
Proxy ph.foo.com behind www.foo.com
12. CORS - <script> tag
Situation:
Website and JS files are on separate domains
(www.foo.com and static.foo.com)
Problem:
Browsers hide error info for cross-origin scripts
Solution:
● Add crossorigin=”anonymous” to <script> tags
● Set up CORS support on static.foo.com webserver
○ Check request’s origin header
○ if OK, add Access-Control-Allow-Origin header
errorMessage:Script error. errorFile: errorLine:0
13. Thank you
Issues and pull requests welcome!
https://github.com/cb372/phone-home
http://phone-home-demo.herokuapp.com/
14. Bonus: Data crunching with ltsv4s
scala> val errors = io.Source.fromFile("ph-errors.log")
.getLines.map(LTSV.parseLine(_, true)).toList
errors: List[Map[String,String]] = ...
scala> errors.map(_("errorMessage")).take(2)
res1: List[String] = List(Script error., Can't find variable: Ajax)
scala> errors.count(_("userAgent").contains("Chrome"))
res2: Int = 15
libraryDependencies += "com.github.seratch" %% "ltsv4s" %
"[0.2,)"
initialCommands in console := "import com.github.seratch.ltsv4s.
_"
build.sbt