This annoys me because of my utmost respect for Chris, but he is unfortunately incorrect. OnPageSetPublishStatus is not fired if your page fails to publish (it is only fired when the publishing status changes - since the failure does not change the last publish date nor the "IsPublished" value, this event wouldn't be fired).
I'm afraid that I have to say that this sounds like a poor man's workaround - if something fails to publish regularly enough for someone to want to get an email whenever it happens, then surely you should address the reasons why it fails to publish, no? A well implemented Tridion system will only fail to publish for valid reasons - like hardware or network failure - and not because it's Friday night or Sunday morning.
Anyway, there's no easy way to monitor this because publishing is a series of processes that happen more-or-less independently.
- The item is queued for publishing (OnPagePublish event)
- The item is picked up by a publisher machine and resolved (OnPageResolve event)
- The item(s) is/are rendered by a publisher (OnPageRender event)
- The item(s) is/are Transported to the deployer (no CM-side events anymore)
- The item(s) is/are deployed to the delivery side with the execution of whatever deployment pipeline you may be using
- The item(s) reports a success status to the CM (OnPageSetPublishedTo event)
- Alternatively the item(s) reports a failed status to the CM - no event triggered because there are no data changes to the page
This is how I would implement such a custom monitoring - up to you to disagree with me.
- Add a custom resolver that determines if any of the items that needs special attention is part of the current publish transaction. You only mention one "Content File" (whatever that means) for now, but I would expect your requirement to quickly expand to other items you (or your customer) didn't consider yet.
- If specialItem is in the list of resolved Items, write to a queue (file system based?) of items to monitor
- Separate process - either a job scheduled to run every 5 minutes, or a service with a timer - checks this queue to see if there's any job requiring attention
- Job loads the publishing queue to check the status of the item's publish transaction
- If that publish transaction is in either failed or success state, notify whomever needs to be notified, modify file queue to state that item is processed and doesn't need additional monitoring
Things to keep in mind:
- You'll have to use two different APIs to interact with Tridion 2009 at this level. The Custom resolver should use TOM.NET while this "external queue monitoring" process should use the COM-based Tridion Object Model
- Once you upgrade, this external process should be rewritten to use the CoreService
- Be prepared to have to start monitoring every transaction instead of just one
- Resolved items may not show in the queue. If I publish a page with 2 components, the 2 components are Resolved Items - but only the page shows in the queue
- You can filter the publishing queue by date and Item being published (and a few more parameters) and as said above, the item being published is not necessarily the item you're monitoring.
- The publisher process may run in multiple machines - but once the resolving is started on one machine, the rest of process is executed by that same machine.
If you have questions about how to implement any of the various things mentioned here, please post them in separate questions.
Last suggestion
Upgrade to Tridion 2011 (or 2013 soon). In 2011 you could use an Event listener on the "Publish Transaction Save" that would give you all the information you need. This is not possible with Tridion 2009.