123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
|
/*******************************************************************************
copyright: Copyright (c) 2004 Kris Bell. All rights reserved
license: BSD style: $(LICENSE)
version: Initial release: May 2004
author: Kris
*******************************************************************************/
module tango.util.log.AppendSocket;
private import tango.util.log.Log;
private import tango.io.Console;
private import tango.io.stream.Buffered;
private import tango.net.device.Socket,
tango.net.InternetAddress;
/*******************************************************************************
Appender for sending formatted output to a Socket.
*******************************************************************************/
public class AppendSocket : Appender
{
private const(char)[] eol;
private Mask mask_;
private Bout buffer;
private Socket conduit;
private InternetAddress address;
private bool connected;
/***********************************************************************
Create with the given Layout and address. Specify an end-
of-line string if you want that appended to each message
***********************************************************************/
this (InternetAddress address, Appender.Layout how = null, const(char)[] eol=null)
{
layout (how);
this.eol = eol;
this.address = address;
this.conduit = new Socket;
this.buffer = new Bout (conduit);
// Get a unique fingerprint for this class
mask_ = register (address.toString());
}
/***********************************************************************
Return the fingerprint for this class
***********************************************************************/
@property override const Mask mask ()
{
return mask_;
}
/***********************************************************************
Return the name of this class
***********************************************************************/
@property override const const(char)[] name ()
{
return this.classinfo.name;
}
/***********************************************************************
Append an event to the output. If the operations fails
we have to revert to an alternative logging strategy,
which will probably require a backup Appender specified
during construction. For now we simply echo to Cerr if
the socket has become unavailable.
***********************************************************************/
override void append (LogEvent event)
{
auto layout = layout();
if (buffer)
{
try {
if (! connected)
{
conduit.connect (address);
connected = true;
}
layout.format (event, &buffer.write);
if (eol.length)
buffer.write (eol);
buffer.flush();
return;
} catch (Exception e)
{
connected = false;
Cerr ("SocketAppender.append :: "~e.toString()).newline;
}
}
Cerr (event.toString()).newline;
}
/***********************************************************************
Close the socket associated with this Appender
***********************************************************************/
override void close ()
{
if (conduit)
conduit.detach();
conduit = null;
}
}
|