Hi michael,
I already send the source code as attachment. Also, the following code:

//////////
> >     if(evaluator->isTriggeringEvent(event))
> >     {
> >             sendBuffer();
> >     }
> > //////////

is fine and dosen't need to be comment. I debugged it and found out that
this snippet sends the log immediately if the level is Error/Fatal. If it's
Debug, it waits for the buffer to get filled before shooting the email. So
everything's working fine. 
The major changes in the classes are, i commented everything related to
libsmtp and used CDO (downloaded from MSDN-exchange sdk along with samples)
which is a com object. I initialize the com object and assign the email
details.
Following are the changes:
1. Import the dependencies:

#import "C:\Program Files\Common Files\system\ado\msado25.tlb" no_namespace
rename("EOF","adoEOF"), named_guids
#import "C:\Program Files\Exchange SDK\SDK\Support\CDO\cdoex.tlb"
no_namespace

//initialize the  com
        hr = CoInitialize(NULL);

//modify the send buffer method

IMessagePtr iMsg(__uuidof(Message));

// Set up a reply.

iMsg->From = bstrFrom;
                
// Set the recipient to the sender of the message that caused the event.
iMsg->To = bstrTo;

LogLog::debug(bstrTo);

// Set up the subject string to contain the subject of the message that
caused the event.

iMsg->Subject = bstrSubject;//ansiSubject;
                
// Set up the text of the message to contain the URL to the message that
caused the event.

iMsg->TextBody = _com_util::ConvertStringToBSTR(T2A((TCHAR
*)s.c_str()));//T2A((TCHAR *)s.c_str());
                
LogLog::debug(_com_util::ConvertStringToBSTR(T2A((TCHAR *)s.c_str()))); 
// Send the message.

                try{
                        LogLog::error(_T("Sending Email"));
                        hr = iMsg->Send();
                }catch (_com_error err){
                        
                        LogLog::error(err.ErrorMessage());
                }
/////////////////////////////////////////////////////////////////
thats it. here's the entire copy/paste of the source file:


/*
 * Copyright 2003,2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
#include <log4cxx/config.h>
#include <comutil.h>
#ifdef HAVE_SMTP

#include <log4cxx/net/smtpappender.h>
#include <log4cxx/level.h>
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/helpers/optionconverter.h>
#include <log4cxx/spi/loggingevent.h>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/stringtokenizer.h>



#import "C:\Program Files\Common Files\system\ado\msado25.tlb" no_namespace
rename("EOF","adoEOF"), named_guids
#import "C:\Program Files\Exchange SDK\SDK\Support\CDO\cdoex.tlb"
no_namespace



extern "C" {
//#include <libsmtp.h>
//#include <libsmtp_mime.h>
}

using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::net;
using namespace log4cxx::spi;

int ReadyCOM();
char * ansiFrom;
char * ansiSubject;
char * ansiTo;
BSTR bstrFrom;
BSTR bstrTo;
BSTR bstrSubject;
int error_code = 0;
char buffer [sizeof(int)*8+1];




IMPLEMENT_LOG4CXX_OBJECT(DefaultEvaluator)
IMPLEMENT_LOG4CXX_OBJECT(SMTPAppender)

bool DefaultEvaluator::isTriggeringEvent(const spi::LoggingEventPtr& event)
{
        return event->getLevel()->isGreaterOrEqual(Level::ERROR);
}

SMTPAppender::SMTPAppender()
: bufferSize(512), locationInfo(false), cb(bufferSize),
evaluator(new DefaultEvaluator()), session(0),
encoding(_T("7bit")), charset(_T("us-ascii"))
{
        if (ReadyCOM() == 1) {
                LogLog::error(_T("Could not initialize CDO com"));
        }
        


}

/**
Use <code>evaluator</code> passed as parameter as the
TriggeringEventEvaluator for this SMTPAppender.  */
SMTPAppender::SMTPAppender(spi::TriggeringEventEvaluatorPtr evaluator)
: bufferSize(512), locationInfo(false), cb(bufferSize),
evaluator(evaluator), session(0),
encoding(_T("7bit")), charset(_T("us-ascii"))
{
}

SMTPAppender::~SMTPAppender()
{
        finalize();
}

void SMTPAppender::setOption(const String& option,
        const String& value)
{
        if (StringHelper::equalsIgnoreCase(option, _T("buffersize")))
        {
                setBufferSize(OptionConverter::toInt(value, 512));
        }
        else if (StringHelper::equalsIgnoreCase(option,
_T("evaluatorclass")))
        {
                setEvaluatorClass(value);
        }
        else if (StringHelper::equalsIgnoreCase(option, _T("from")))
        {
                setFrom(value);
        }
        else if (StringHelper::equalsIgnoreCase(option, _T("smtphost")))
        {
                setSMTPHost(value);
        }
        else if (StringHelper::equalsIgnoreCase(option, _T("subject")))
        {
                setSubject(value);
        }
        else if (StringHelper::equalsIgnoreCase(option, _T("to")))
        {
                setTo(value);
        }
        else if (StringHelper::equalsIgnoreCase(option, _T("charset")))
        {
                setCharset(value);
        }
        else if (StringHelper::equalsIgnoreCase(option, _T("encoding")))
        {
                setEncoding(value);
        }
        else
        {
                AppenderSkeleton::setOption(name, value);
        }
}

/**
Activate the specified options, such as the smtp host, the
recipient, from, etc. */
void SMTPAppender::activateOptions()
{
        USES_CONVERSION;

//      session = ::libsmtp_session_initialize();
//      if (session == 0)
//      {
//              LogLog::error(_T("Could not intialize session."));
//              return;
//      }

        ansiFrom = T2A((TCHAR *)from.c_str());
        LogLog::error(_T("from:"));
        
        bstrFrom = _com_util::ConvertStringToBSTR(ansiFrom);
        LogLog::error(bstrFrom);
        LogLog::error(_T("subject:"));
        ansiSubject = T2A((TCHAR *)subject.c_str());
        bstrSubject = _com_util::ConvertStringToBSTR(ansiSubject);
        LogLog::error(bstrSubject);

        
        /*
        ::libsmtp_set_environment(
                ansiFrom,
                ansiSubject,
                0,
                (libsmtp_session_struct *)session);
        */
        

        std::vector<String> recipients = parseAddress(to);
        std::vector<String>::iterator i;
        for (i = recipients.begin(); i != recipients.end(); i++)
        {
                /*
                if (::libsmtp_add_recipient(LIBSMTP_REC_TO,
                        (TCHAR *)T2A(i->c_str()),
                        (libsmtp_session_struct *)session) != 0)
                {
                        LogLog::error(_T("Could not add recipient
")+*i+_T("."));
                        return;
                }
                */
//              ansiTo = (TCHAR *)T2A(i->c_str());
//              char * thisVal = A2W(i->c_str());
                ansiTo = T2A((TCHAR *)i->c_str());
                bstrTo = _com_util::ConvertStringToBSTR(ansiTo);
                LogLog::error(_T("To:"));
                LogLog::error(bstrTo);

        }


        // MIMEPART
        if (layout != 0)
        {
                int mimeType = 0;
                String contentType = layout->getContentType();
                if (contentType == _T("text/plain"))
                {
//                      mimeType = LIBSMTP_MIME_SUB_PLAIN;
                }
                else if (contentType == _T("text/html"))
                {
//                      mimeType = LIBSMTP_MIME_SUB_HTML;
                }
                else
                {
                        LogLog::error(_T("invalid layout content type:
")+contentType+_T("."));
                        return;
                }

                int charset = 0;
/*              
                if (this->charset == _T("us-ascii"))
                {
                         charset = LIBSMTP_CHARSET_USASCII;
                }
                else if (this->charset == _T("iso8859_1"))
                {
                         charset = LIBSMTP_CHARSET_ISO8859_1;
                }
                else if (this->charset == _T("iso8859_2"))
                {
                         charset = LIBSMTP_CHARSET_ISO8859_2;
                }
                else if (this->charset == _T("iso8859_3"))
                {
                         charset = LIBSMTP_CHARSET_ISO8859_3;
                }
                else
                {
                        LogLog::error(_T("invalid charset:
")+this->charset+_T("."));
                        return;
                }
*/

                int encoding = 0;
/*
                if (this->encoding == _T("7bit"))
                {
                        encoding = LIBSMTP_ENC_7BIT;
                }
                else if (this->encoding == _T("8bit"))
                {
                        encoding = LIBSMTP_ENC_8BIT;
                }
                else if (this->encoding == _T("binary"))
                {
                        encoding = LIBSMTP_ENC_BINARY;
                }
                else if (this->encoding == _T("base64"))
                {
                        encoding = LIBSMTP_ENC_BASE64;
                }
                else if (this->encoding == _T("quoted"))
                {
                        encoding = LIBSMTP_ENC_QUOTED;
                }
                else
                {
                        LogLog::error(_T("invalid encoding:
")+this->encoding+_T("."));
                        return;
                }
*/
/*
                libsmtp_part_struct * part = 0;
                part = ::libsmtp_part_new(
                        0,
                        LIBSMTP_MIME_TEXT,
                        mimeType,
                        encoding,
                        charset,
                        "content",
                        (libsmtp_session_struct *)session);
                if (part == 0)
                {
                        LogLog::error(_T("Error adding part."));
                }
*/
        }
        else
        {
                LogLog::error(_T("Layout not set !"));
        }
}

/**
Perform SMTPAppender specific appending actions, mainly adding
the event to a cyclic buffer and checking if the event triggers
an e-mail to be sent. */
void SMTPAppender::append(const spi::LoggingEventPtr& event)
{
        if(!checkEntryConditions())
        {
                return;
        }

        event->getNDC();

/*      if(locationInfo)
        {
                event.getLocationInformation();
        }*/

        cb.add(event);

        if(evaluator->isTriggeringEvent(event))
        {
                sendBuffer();
        }
}

/**
This method determines if there is a sense in attempting to append.
<p>It checks whether there is a set output target and also if
there is a set layout. If these checks fail, then the boolean
value <code>false</code> is returned. */
bool SMTPAppender::checkEntryConditions()
{
        if(to.empty() || from.empty() || subject.empty() ||
smtpHost.empty())
        {

                errorHandler->error(_T("Message not configured."));
                return false;
        }

        if(evaluator == 0)
        {
                errorHandler->error(_T("No TriggeringEventEvaluator is set
for appender [")+
                        name+_T("]."));
                return false;
        }

/*
        if(layout == 0)
        {
                errorHandler->error(_T("No layout set for appender named
[")+name+_T("]."));
                return false;
        }

*/
        return true;

}

void SMTPAppender::close()
{
        synchronized sync(this);
        /*
        if (!this->closed && session != 0)
        {
                ::libsmtp_free((libsmtp_session_struct *)session);
                session = 0;
        }
        */
        this->closed = true;
}

std::vector<String> SMTPAppender::parseAddress(const String& addressStr)
{
        std::vector<String> addresses;

        StringTokenizer st(addressStr, _T(","));
        while (st.hasMoreTokens())
        {
                addresses.push_back(st.nextToken());
        }

        return addresses;
}

/**
Send the contents of the cyclic buffer as an e-mail message.
*/
void SMTPAppender::sendBuffer()
{
        // Note: this code already owns the monitor for this
        // appender. This frees us from needing to synchronize on 'cb'.
        try
        {
                USES_CONVERSION;
                StringBuffer sbuf;
                layout->appendHeader(sbuf);

                int len = cb.length();
                for(int i = 0; i < len; i++)
                {
        
//sbuf.append(MimeUtility.encodeText(layout.format(cb.get())));
                        LoggingEventPtr event = cb.get();
                        layout->format(sbuf, event);
                }

                layout->appendFooter(sbuf);

                /* This starts the SMTP connection */
                /*
                if (::libsmtp_connect(
                        T2A((TCHAR *)smtpHost.c_str()),
                        0,
                        0,
                        (libsmtp_session_struct *)session) != 0)
                {
                        LogLog::error(_T("Error occured while starting the
SMTP connection."));
                        return;
                }
                */
                /* This will conduct the SMTP dialogue */

/*
                if (::libsmtp_dialogue((libsmtp_session_struct *)session) !=
0)
                {
                        LogLog::error(_T("Error occured while conducting the
SMTP dialogue."));
                        return;
                }
*/
                /* Now lets send the headers */
/*
                if (::libsmtp_headers((libsmtp_session_struct *)session) !=
0)
                {
                        LogLog::error(_T("Error occured while sending the
headers."));
                        return;
                }
*/
                /* Now lets send the MIME headers */
/*
                if (::libsmtp_mime_headers((libsmtp_session_struct
*)session) != 0)
                {
                        LogLog::error(_T("Error occured while sending the
MIME headers."));
                        return;
                }
*/
                String s = sbuf.str();
                
                HRESULT hr;

                // Create a new message.
                IMessagePtr iMsg(__uuidof(Message));

                // Set up a reply.
                iMsg->From = bstrFrom;
                

                
                // Set the recipient to the sender of the message that
caused the event.
                iMsg->To = bstrTo;

                LogLog::debug(bstrTo);

                // Set up the subject string to contain the subject of the
message that caused the event.
                iMsg->Subject = bstrSubject;//ansiSubject;
                
                // Set up the text of the message to contain the URL to the
message that caused the event.
                iMsg->TextBody = _com_util::ConvertStringToBSTR(T2A((TCHAR
*)s.c_str()));//T2A((TCHAR *)s.c_str());
                
                LogLog::debug(_com_util::ConvertStringToBSTR(T2A((TCHAR
*)s.c_str()))); 
                // Send the message.
                try{
                        LogLog::error(_T("Sending Email"));
                        hr = iMsg->Send();
                }catch (_com_error err){
                        
                        LogLog::error(err.ErrorMessage());
                }
//              LogLog::error(_T("Don't know if error occured while sending
the message body."));
                /*
                if (::libsmtp_part_send(
                        T2A((TCHAR *)s.c_str()),
                        s.length(),
                        (libsmtp_session_struct *)session) != 0)
                {
                        LogLog::error(_T("Error occured while sending the
message body."));
                }
                */
                /* This ends the body part */
/*
                if (::libsmtp_body_end((libsmtp_session_struct *)session) !=
0)
                {
                        LogLog::error(_T("Error occured while ending the
body part."));
                        return;
                }
*/
                /* This ends the connection gracefully */
/*
                if (::libsmtp_quit((libsmtp_session_struct *)session) != 0)
                {
                        LogLog::error(_T("Error occured while ending the
connection."));
                        return;
                }
*/
        }
        catch(Exception& e)
        {
                LogLog::error(_T("Error occured while sending e-mail
notification."), e);
        }
}

/**
Returns value of the <b>EvaluatorClass</b> option.
*/
String SMTPAppender::getEvaluatorClass()
{
        return evaluator == 0 ? String() : evaluator->getClass().getName();
}

/**
The <b>BufferSize</b> option takes a positive integer
representing the maximum number of logging events to collect in a
cyclic buffer. When the <code>BufferSize</code> is reached,
oldest events are deleted as new events are added to the
buffer. By default the size of the cyclic buffer is 512 events.
*/
void SMTPAppender::setBufferSize(int bufferSize)
{
        this->bufferSize = bufferSize;
        cb.resize(bufferSize);
}

/**
The <b>EvaluatorClass</b> option takes a string value
representing the name of the class implementing the [EMAIL PROTECTED]
TriggeringEventEvaluator} interface. A corresponding object will
be instantiated and assigned as the triggering event evaluator
for the SMTPAppender.
*/
void SMTPAppender::setEvaluatorClass(const String& value)
{
        evaluator = OptionConverter::instantiateByClassName(value,
                TriggeringEventEvaluator::getStaticClass(), evaluator);
}

#endif //HAVE_SMTP

int ReadyCOM()
{
        HRESULT hr;

        hr = CoInitialize(NULL);

        if (FAILED(hr))
        {

                //cout << "COM Initialization Failed." << endl;


                return 1;

        }

        return 0;
}

Reply via email to