blob: b084db5a6c33099f16e939df2ebda6c9e042fa68 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 <windows.h>
#include <string>
#include <limits>
#include <vector>
#include <iostream>
#include <assert.h>
#include "qpid/messaging/Logger.h"
#include "qpid/messaging/exceptions.h"
#include "qpid/types/Variant.h"
#include "Logger.h"
#include "QpidException.h"
#include "QpidMarshal.h"
/// <summary>
/// outputCallbackHost
/// Native class that holds reference to managed class
/// and for hosting the native callback procedure.
/// </summary>
namespace qpid {
namespace messaging {
class outputCallbackHost : public qpid::messaging::LoggerOutput {
private:
// Reference to managed class
gcroot<Org::Apache::Qpid::Messaging::LoggerOutput^> m_loggerOutput;
public:
outputCallbackHost(Org::Apache::Qpid::Messaging::LoggerOutput ^ _m_loggerOutput)
: m_loggerOutput(_m_loggerOutput)
{
}
~outputCallbackHost()
{
}
// Native callback entry point called by qpid Logger
void log(qpid::messaging::Level level, bool user, const char* file, int line,
const char* function, const std::string& message)
{
m_loggerOutput->Log(level, user, file, line, function, message);
}
};
}}
namespace Org {
namespace Apache {
namespace Qpid {
namespace Messaging {
///
/// Managed class with desired delegate
///
LoggerOutput::LoggerOutput( LoggerOutputCallback^ callback)
: loggerDelegate(callback),
interceptor(new qpid::messaging::outputCallbackHost(this))
{
::qpid::messaging::Logger::setOutput(*interceptor);
}
LoggerOutput::~LoggerOutput()
{
}
// Relay log message to managed code
void LoggerOutput::Log(
qpid::messaging::Level level,
bool user,
const char* file,
int line,
const char* function,
const std::string& message)
{
// create managed log args
Messaging::Level mLevel = (Messaging::Level)level;
System::Boolean mUser = user;
System::String^ mFile = gcnew String( file );
System::Int32 mLine = line;
System::String^ mFunction = gcnew String( function );
System::String^ mMessage = gcnew String( message.c_str() );
// pass to delegate
loggerDelegate( mLevel, mUser, mFile, mLine, mFunction, mMessage );
}
/// <summary>
/// Logger a managed wrapper for a ::qpid::messaging::Logger
/// </summary>
// Constructor
Logger::Logger()
{
// Sanity check that managed == native enum values
assert((int)Messaging::Level::trace == (int)::qpid::messaging::trace);
assert((int)Messaging::Level::debug == (int)::qpid::messaging::debug);
assert((int)Messaging::Level::info == (int)::qpid::messaging::info);
assert((int)Messaging::Level::notice == (int)::qpid::messaging::notice);
assert((int)Messaging::Level::warning == (int)::qpid::messaging::warning);
assert((int)Messaging::Level::error == (int)::qpid::messaging::error);
assert((int)Messaging::Level::critical == (int)::qpid::messaging::critical);
}
// Destructor
Logger::~Logger()
{
this->!Logger();
}
// Finalizer
Logger::!Logger()
{
}
void Logger::Configure(array<System::String ^> ^ args)
{
Configure(args, "");
}
void Logger::Configure(array<System::String ^> ^ theArgs, System::String ^ thePrefix)
{
System::Exception ^ newException = nullptr;
try
{
// Marshal the calling args
int argc = theArgs->Length;
std::vector<std::string> cppStrings;
for (int i=0; i<argc; i++)
{
cppStrings.push_back ( QpidMarshal::ToNative( theArgs[i] ) );
}
std::vector<const char *> cStrings;
for (int i=0; i<argc; i++)
{
cStrings.push_back ( cppStrings[i].c_str() );
}
const char** argv = &cStrings[0];
std::string prefix = QpidMarshal::ToNative(thePrefix);
// configure
::qpid::messaging::Logger::configure(argc, argv, prefix);
}
catch (const ::qpid::types::Exception & error)
{
String ^ errmsg = gcnew String(error.what());
newException = gcnew QpidException(errmsg);
}
if (newException != nullptr)
{
throw newException;
}
}
System::String ^ Logger::Usage()
{
return gcnew String(::qpid::messaging::Logger::usage().c_str());
}
// Inject a log message from managed user space into unmanaged
// Qpid Messaging log stream.
void Logger::Log(
Messaging::Level level,
System::String^ file,
System::Int32 line,
System::String^ function,
System::String^ message)
{
// create unmanaged log args
qpid::messaging::Level nLevel = (qpid::messaging::Level)level;
std::string nFile = QpidMarshal::ToNative(file);
int nLine = line;
std::string nFunction = QpidMarshal::ToNative(function);
const std::string nMessage = QpidMarshal::ToNative(message);
System::Exception ^ newException = nullptr;
try
{
// pass to native log engine
::qpid::messaging::Logger::log(
nLevel, nFile.c_str(), line, nFunction.c_str(), nMessage);
}
catch (const ::qpid::types::Exception & error)
{
String ^ errmsg = gcnew String(error.what());
newException = gcnew QpidException(errmsg);
}
if (newException != nullptr)
{
throw newException;
}
}
}}}}