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 }