3

I need to perform some action when the component is published successfully.I have used below code and writeout the logs.

EventSystem.Subscribe<PublishTransaction, SaveEventArgs>(TransactionSaved, EventPhases.TransactionCommitted);

public void TransactionSaved(PublishTransaction transaction, SaveEventArgs args, EventPhases phases)
{
    StreamWriter writer = File.AppendText(@"F:\log\Log.txt");
    if (transaction.State == PublishTransactionState.Success)
    {
        writer.WriteLine("PublishTransactionState : success");
        //Code To DO
    }
    else
    {
        writer.WriteLine("PublishTransactionState : " + transaction.State.ToString());
    }
}

But, If i publish any item and check the logs after the component success. The code part written for success didn't execute. Always my log shows "Waiting for Publish" in it.

Can anyone help me out to fix this ?

Thanks in Advance.

4
  • Is your publish transaction actually being published? Or is it also showing as "Waiting to Publish" in the Publish Queue in the GUI? Aug 3, 2013 at 13:57
  • Frank, After restarting the publishing service.I can get the publish status as "success". But i am facing one more issue.For few components i am getting success status properly. Some times transactions are ended up in "WaitingForDeployment" but if i saw the publish queue the transaction is success.
    – user646
    Aug 4, 2013 at 10:23
  • Firstly - please don't answer Frank's comment with an answer to the question. That will just confuse everyone. Even as a comment, your response would be confusing. Please try to make it clear to everyone what the issue is, and any insights you have already gained as to its solution. Aug 4, 2013 at 21:51
  • I've moved the answer into a comment, but @user645 please edit the question and clarify what your issue is. It is okay to edit your own question multiple times to add new insights to change the original issue into a new one if the original is solved. Aug 5, 2013 at 7:55

2 Answers 2

4

Instead of using SaveEventArgs on publish transaction, which is triggered for every state change i.e. Rendering, Resolving, Transporting, etc, use SetPublishStateEventArgs which is triggered only once when item is successfully published or unpublished. Since you are doing it on a component the best way to subscribe will be:

    public void Subscribe()
    {           
        EventSystem.Subscribe<Component, SetPublishStateEventArgs>(Handler, EventPhases.TransactionCommitted);            
    }

    private void Handler(IdentifiableObject subject, SetPublishStateEventArgs args, EventPhases phase)
    {
        File.AppendAllText("c:\\log\\log.txt", args.IsPublished.ToString() + "\r\n");
    }

Disregard the beauty of the code in the Handler, but it will basically return you True or Fasle, depending if item was published or unpublished. It will also work if component was published as a result of publishing Page, or Bundle.

From SDL Tridion 2013 on you can also subscribe to PublishTransaction SetPublishStateEventArgs to catch all of the publish actions and not only components, click here for details

1

After creating an Event Handler and registering it in the Tridion.ContentManager.config you have to make sure you restart the appropriate services to make sure your changes are picked up. This always starts with stopping the SDL Tridion Content Manager COM+ application (it automatically restarts, so a stop is enough), and restarting the Tridion Content Manager Service Host. But when you are using publishing events, you have to make sure you restart the Publisher and Transport service too.

In most cases it's better safe than to be sorry and use a restart script like this on your development environment. For the production server a reboot is always what I like to see after a deploy (but that's personal preference).

Then looking at your code sample, you are using a StreamWriter without properly closing or disposing it. This way you can never be sure when your updates will actually be written to your log file. Also when multiple threads are triggering your event, this code will probably not work well. I would recommend at least something like:

using (StreamWriter writer = File.AppendText(@"F:\log\Log.txt"))
{
    if (transaction.State == PublishTransactionState.Success)
    {
        writer.WriteLine("PublishTransactionState : success");
        //Code To DO
    }
    else
    {
        writer.WriteLine(string.Format("PublishTransactionState : {0}", transaction.State));
    }
}

But personally (although officially not supported because it is not an open API) I prefer to log to the Tridion Event Viewer Log. To do that, you can add the following using statement:

using Tridion.Logging;

Make sure you have a reference to the Tridion.Logging.dll (which you can find in your ..\Tridion\bin\client folder), and then you can use the following line of code to log your messages:

Logger.Write("my message", "MyEventHandlerName", LoggingCategory.General, TraceEventType.Information);

by selecting a different TraceEventType, you can also log critical, error, warning and verbose (debug) messages. These messages are thread safe and will always directly appear (given that you configured the correct logging level in the MMC snap-in), or simply log everything as an error while you are developing so you know that it will show up ;o).

2
  • So how does it answer the question? The problem is not that no event is logged, but that what is logged is not what is expected? Aug 5, 2013 at 9:13
  • 1
    @user978511 reading the comments the entire question is actually not clear at all to me, so starting out with proper programming will help in getting correct results is what I figured. With the correct logging the OP will notice that his event is called multiple times as you indicate in your answer ;o). Aug 5, 2013 at 9:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.