1 /******************************************************************************* 2 3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved 4 5 license: BSD style: $(LICENSE) 6 7 version: Initial release: May 2004 8 9 author: Kris 10 11 *******************************************************************************/ 12 13 module tango.util.log.AppendSocket; 14 15 private import tango.util.log.Log; 16 17 private import tango.io.Console; 18 19 private import tango.io.stream.Buffered; 20 21 private import tango.net.device.Socket, 22 tango.net.InternetAddress; 23 24 /******************************************************************************* 25 26 Appender for sending formatted output to a Socket. 27 28 *******************************************************************************/ 29 30 public class AppendSocket : Appender 31 { 32 private const(char)[] eol; 33 private Mask mask_; 34 private Bout buffer; 35 private Socket conduit; 36 private InternetAddress address; 37 private bool connected; 38 39 /*********************************************************************** 40 41 Create with the given Layout and address. Specify an end- 42 of-line string if you want that appended to each message 43 44 ***********************************************************************/ 45 46 this (InternetAddress address, Appender.Layout how = null, const(char)[] eol=null) 47 { 48 layout (how); 49 50 this.eol = eol; 51 this.address = address; 52 this.conduit = new Socket; 53 this.buffer = new Bout (conduit); 54 55 // Get a unique fingerprint for this class 56 mask_ = register (address.toString()); 57 } 58 59 /*********************************************************************** 60 61 Return the fingerprint for this class 62 63 ***********************************************************************/ 64 65 @property override const Mask mask () 66 { 67 return mask_; 68 } 69 70 /*********************************************************************** 71 72 Return the name of this class 73 74 ***********************************************************************/ 75 76 @property override const const(char)[] name () 77 { 78 return this.classinfo.name; 79 } 80 81 /*********************************************************************** 82 83 Append an event to the output. If the operations fails 84 we have to revert to an alternative logging strategy, 85 which will probably require a backup Appender specified 86 during construction. For now we simply echo to Cerr if 87 the socket has become unavailable. 88 89 ***********************************************************************/ 90 91 override void append (LogEvent event) 92 { 93 auto layout = layout(); 94 95 if (buffer) 96 { 97 try { 98 if (! connected) 99 { 100 conduit.connect (address); 101 connected = true; 102 } 103 104 layout.format (event, &buffer.write); 105 if (eol.length) 106 buffer.write (eol); 107 buffer.flush(); 108 return; 109 } catch (Exception e) 110 { 111 connected = false; 112 Cerr ("SocketAppender.append :: "~e.toString()).newline; 113 } 114 } 115 116 Cerr (event.toString()).newline; 117 } 118 119 /*********************************************************************** 120 121 Close the socket associated with this Appender 122 123 ***********************************************************************/ 124 125 override void close () 126 { 127 if (conduit) 128 conduit.detach(); 129 conduit = null; 130 } 131 }