Friday, February 21, 2014

Fixing Outlook synchronization issue 0x000710D2 (no instances) when synchronizing Google Calendar

I got annoyed with the following warning whenever Outlook synchronized my Google Calendar: Task 'Internet Calendar Subscriptions' reported error (0x000710D2) : 'The VEVENT, "...", defined near line ..., contains a recurrence pattern that has no instances.'

So I downloaded the ICS (via the URL you had to enter when configuring the synchronization between Outlook and Google Calendar) and looked at the VEVENT at the specified line. There I found the name of the event and went to Google Calender to delete the problematic event. Alas, bummer: the search did not show up the event. Nor did scrolling through the calendar within the date range of the VEVENT.

So instead I made friends with the Google API explorer:

  1. Go into Outlook account settings, find your internet calendar, and copy the URL address of the calendar.
  2. Paste that URL into a browser and go. Choose "save" When asked to save or open the file.
  3. Open the downloaded text file with some application that shows line numbers. Most text editors will do. You might as well use MS Excel.
  4. Scroll down to the vicinity of the line number cited in the offending error message. Verify that this is the troublemaker, and then find the line starting “UID: “. This is the iCalUID that you will need later.
  5. Go to the Google Calendar API
  6. Enable authentication with the OAuth slider on the right. A dialog "Select OAuth 2.0 scopes" pops up. Check both options and click Authorize
  7. Click calendar.calendarList.list and then Execute on the following page. Below the Execute button, two headlines Request and Response. If the Response is 401 Unauthorized, the previous step has failed. Try again. Otherwise you get a list of your calendars with each entry starting like this: { "kind": "calendar#calendarListEntry", "etag": ... "id": "THIS IS THE ID OF THE CALENDAR", "summary": "THIS IS THE NAME OF THE CALENDAR", Put down the ID of the calendar. The ID of your main calendar seems to be identical with your email address.
  8. Use calendar.events.list with the calendar ID and the iCalUID from the ICS. You should get only a single entry like this: { "kind": "calendar#event", "etag": ... "id": "THE ID THAT WE NEED", "status": "confirmed", ... "summary": "THIS IS THE NAME OF THE EVENT", ... Put down the ID of the event. This ID seems to be just the same as the one in the ICS without @google.com at the. Just specifying the calendar ID should show up ALL events, but the problematic event showed up only if you specified its iCalUID.
  9. Use calendar.events.delete with the calendar ID and event ID to delete the event. Problem solved!

In hindsight, you may as well go directly to calendar.events.delete and use your email address for calendarId and the ID from the ICS without @google.com for eventId. But no guarantee.

Now this was really fun. Felt a little like debugging sendmail via telnet on 25.

Update on May 28th 2014 because authorizaton changed and more explicit steps were requested.

Update on July 15th 2014: more details how to get the iCalUID. Thanks to Linda Stoutenburgh!

Thursday, February 20, 2014

Logging best practices and binary logger

The splunk website offers some logging best practices that I'd like to compare with binary logger, a small library I wrote to reduce the load caused by logging on small embedded devices.

Here are the best practices and how binary logger relates to them:

  • Use clear key-value pairs. This is also called structured logging and is one of the techniques recommended to try by the latest ThoughtWorks technology radar. With binary logger this is possible without ANY additional load on the embedded device (not ROM, not RAM, not CPU, not bandwidth).
  • Create events that humans can read. Obviously, binary logger can't offer this. You need a script (provided with the library) and the originally source code to decipher the binary log stream. On the other hand you can be really verbose in the decrypted log and strive for maximum readability without any load on the embedded device.
  • Use timestamps for every event. Do it! It doesn't cost you much with binary logger.
  • Use unique identifiers (IDs). See last point.
  • Log in text format. Again, this is where binary logger has its weakness.
  • Use developer-friendly formats. See first point: you are rather free in the format because it doesn't cost you any load on the embedded device.
  • Log more than just debugging events. Because logging with binary logger is very cheap on resources like stack, you might add logging messages where you couldn't with a standard logging facility.
  • Use categories. Adding categories to log messages costs you nothing on the embedded device with binary logger if you add them as static text.
  • Identify the source. The binary log stream format automatically contains the source of any log event, because it's needed for deciphering the binary log stream.
  • Keep multi-line events to a minimum. Do as you like with binary logger.

I think the above best practices are really good advice. Binary logger might help you to follow them when the constraints of your embedded device would normally let you refrain from it. I'd love your feedback on this post and binary logger!