1 /*******************************************************************************
2 
3    Copyright:
4        Copyright (c) 2004 Kris Bell.
5        Some parts copyright (c) 2009-2016 dunnhumby Germany GmbH.
6        All rights reserved.
7 
8    License:
9        Tango Dual License: 3-Clause BSD License / Academic Free License v3.0.
10        See LICENSE_TANGO.txt for details.
11 
12    Version: Initial release: May 2004
13 
14    Authors: Kris
15 
16 *******************************************************************************/
17 
18 module ocean.util.log.AppendFile;
19 
20 import ocean.io.device.File;
21 import ocean.io.model.IFile;
22 import ocean.io.model.IConduit;
23 import ocean.io.stream.Buffered;
24 import ocean.meta.types.Qualifiers;
25 import ocean.util.log.Appender;
26 import ocean.util.log.Event;
27 
28 /*******************************************************************************
29 
30     Append log messages to a file. This basic version has no rollover support,
31     so it just keeps on adding to the file.
32 
33     There is also an AppendFiles that may suit your needs.
34 
35 *******************************************************************************/
36 
37 public class AppendFile : Filer
38 {
39    private Mask mask_;
40 
41     /// File to append to
42     private File    file_;
43 
44     /***************************************************************************
45 
46         Create a basic FileAppender to a file with the specified path.
47 
48     ***************************************************************************/
49 
50     public this (istring fp, Appender.Layout how = null)
51     {
52         // Get a unique fingerprint for this instance
53         this.mask_ = register(fp);
54 
55         // make it shareable for read
56         File.Style style = File.WriteAppending;
57         style.share = File.Share.Read;
58         this.file_ = new File(fp, style);
59         configure (this.file_);
60         this.layout(how);
61     }
62 
63     /***************************************************************************
64 
65         Returns:
66             the fingerprint for this class
67 
68     ***************************************************************************/
69 
70     final override Mask mask ()
71     {
72         return mask_;
73     }
74 
75     /***************************************************************************
76 
77         Return the name of this class
78 
79     ***************************************************************************/
80 
81     final override istring name ()
82     {
83         return this.classinfo.name;
84     }
85 
86     /***********************************************************************
87 
88             File that this appender appends to.
89 
90     ***********************************************************************/
91 
92     File file ()
93     {
94         return this.file_;
95     }
96 
97     /***********************************************************************
98 
99         Append an event to the output.
100 
101     ***************************************************************************/
102 
103     final override void append (LogEvent event)
104     {
105         this.layout.format(event, (cstring v) { this.buffer.write(v); });
106         this.buffer.append(FileConst.NewlineString).flush;
107     }
108 }
109 
110 
111 /// Base class for file appenders
112 public class Filer : Appender
113 {
114     package Bout            buffer;
115     private IConduit        conduit_;
116 
117     /***************************************************************************
118 
119         Return the conduit
120 
121     ***************************************************************************/
122 
123     final IConduit conduit ()
124     {
125         return this.conduit_;
126     }
127 
128     /***************************************************************************
129 
130         Close the file associated with this Appender
131 
132     ***************************************************************************/
133 
134     final override void close ()
135     {
136         if (this.conduit_)
137         {
138             this.conduit_.detach;
139             this.conduit_ = null;
140         }
141     }
142 
143     /***************************************************************************
144 
145         Set the conduit
146 
147     ***************************************************************************/
148 
149     package final Bout configure (IConduit conduit)
150     {
151         // create a new buffer upon this conduit
152         this.conduit_ = conduit;
153         return (this.buffer = new Bout(conduit));
154     }
155 }