Go to Monitoring>Debug log.
Where you would normally put the username, put the name of the Site.
For example:
If your site is called MySite, enter MySite as the user name. Shockingly undocumented, but this gives you the debug you're looking for.
ATTENTION:
Winter17 is making a change to this--you'll now need to ALSO set a specific cookie in the guest user's browser to enable this.
https://releasenotes.docs.salesforce.com/en-us/winter17/release-notes/rn_forcecom_debugging_guest_user.htm#rn_forcecom_debugging_guest_user
Related Idea Exchange Idea for Integrations
The requirement for such a cookie is incompatible when building web-hook services for 3rd parties, there is an Idea Exchange post here to provide an IP whitelist as an alternative.
Update from Spring '18 release notes:
In Winter ’17, we introduced a change that required guest users to set browser cookies to activate debug logging. We had the best of intentions: All your public site visitors share one guest user license. Thus, when you enable logging for the guest user, the visitors’ collective activities can fill your debug logs quickly, hitting the log-size limit and causing log truncation. Sadly, people didn’t like the Winter ’17 change. Setting cookies is complicated, and the change made collecting debug logs for public users’ asynchronous activity impossible. We’ve seen the error of our ways. Your public users no longer need a debug_logs browser cookie to trigger logging. This change applies to both Lightning Experience and Salesforce Classic.
Try one or more of the following:
Set the debug level to be less verbose (dev console). You'll get major errors back rather than each loop iteration showing up.
There are visualforce global parameters for page and exception. I placed these in a google analytics event on the page so I can see what's being thrown.
Wrap the whole page in a try/catch block, and do a system.debug(logginglevel.error, e) in the last catch. <==assuming you name all your exceptions e like I do). If the log verbosity is the main problem, combine this with #1.
If the error happens after the page loads, like on a save or other action, you could do #3 but use an apex message option to show the error that you're catching on the page (avoid the logs entirely).
Here's the GA script we use (prerequisite is that you have the GA async tag already on the page AND you have your GA id on the salesforce site config page).
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', '{!$Site.AnalyticsTrackingCode}']);
_gaq.push([
'_trackEvent',
'Page Errors',
'{!$Site.ErrorMessage}',
'{!$Site.OriginalUrl}--{!$Site.ErrorDescription} experienced by {!$User.id}']);
</script>
Best of luck!
Best Answer
It might be related to the Debug Logs issue known by Salesforce since Winter'14. I couldn't set up the debug logs for some users. Here is how to fix it : here. It worked perfectly for me.