1 /** @file oils_config.js
2 * Config code and Logger code
3 * The config module is simple. It parses an xml config file and
4 * the values from the file are accessed via XPATH queries.
7 /** Searches up from Mozilla's chrome directory for the client
8 * config file and returns the file object
10 function get_config_file() {
12 var dirService = Components.classes["@mozilla.org/file/directory_service;1"].
13 getService( Components.interfaces.nsIProperties );
15 chromeDir = dirService.get( "AChrom", Components.interfaces.nsIFile );
16 chromeDir.append(myPackageDir);
17 chromeDir.append("content");
18 chromeDir.append("conf");
19 chromeDir.append("client_config.xml");
25 /** Constructor. You may provide an optional path to the config file. **/
26 function Config( config_file ) {
28 if( Config.config != null ) { return Config.config; }
30 config_file = get_config_file();
32 // ------------------------------------------------------------------
33 // Grab the data from the config file
34 // ------------------------------------------------------------------
36 var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
37 .createInstance(Components.interfaces.nsIFileInputStream);
39 var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"]
40 .createInstance(Components.interfaces.nsIScriptableInputStream);
42 fstream.init(config_file, 1, 0, false);
43 sstream.init(fstream);
44 data += sstream.read(-1);
51 var DOMParser = new Components.Constructor(
52 "@mozilla.org/xmlextras/domparser;1", "nsIDOMParser" );
54 this.config_doc = new DOMParser().parseFromString( data, "text/xml" );
60 /** Returns the value stored in the config file found with the
61 * given xpath expression
62 * E.g. config.get_value( "/oils_config/dirs/log_dir" );
63 * Note, the 'oils_config' node is the base of the xpath expression,
64 * so something like this will also work:
65 * config.get_value( "dirs/log_dir" );
67 Config.prototype.get_value = function( xpath_query ) {
69 var evaluator = Components.classes["@mozilla.org/dom/xpath-evaluator;1"].
70 createInstance( Components.interfaces.nsIDOMXPathEvaluator );
72 var xpath_obj = evaluator.evaluate( xpath_query, this.config_doc.documentElement, null, 0, null );
73 if( ! xpath_obj ) { return null; }
75 var node = xpath_obj.iterateNext();
77 throw new oils_ex_config( "No config option matching " + xpath_query );
80 return node.firstChild.nodeValue;
88 // ------------------------------------------------------------------
90 // ------------------------------------------------------------------
91 /** The global logging object */
93 /** No logging level */
95 /** Error log level */
102 /** There exists a single logger object that all components share.
103 * Calling var logger = new Logger() will return the same one
104 * with each call. This is so we only need one file handle for
105 * each type of log file.
109 if( Logger.logger != null ) { return Logger.logger }
111 var config = new Config();
112 this.log_level = config.get_value( "system/log_level" );
114 this.stdout_log = config.get_value( "system/stdout_log" );
116 if( ! this.stdout_log || this.stdout_log < 0 || this.stdout_log > 2 ) {
117 throw new oils_ex_config( "stdout_log setting is invalid: " + this.stdout_log +
118 ". Should be 0, 1, or 2." );
121 // ------------------------------------------------------------------
122 // Load up all of the log files
123 // ------------------------------------------------------------------
124 var transport_file = config.get_value( "logs/transport" );
125 if( transport_file == null ) {
126 throw new oils_ex_config( "Unable to load transport log file: 'logs/transport'" );
129 var debug_file = config.get_value( "logs/debug" );
130 if( debug_file == null ) {
131 throw new oils_ex_config( "Unable to load debug log file: 'logs/debug'" );
134 var error_file = config.get_value( "logs/error" );
135 if( error_file == null ) {
136 throw new oils_ex_config( "Unable to load debug log file: 'logs/error'" );
140 // ------------------------------------------------------------------
141 // Build the file objects
142 // ------------------------------------------------------------------
143 var transport_file_obj = Logger.get_log_file( transport_file );
145 var debug_file_obj = Logger.get_log_file( debug_file );
147 var error_file_obj = Logger.get_log_file( error_file );
150 // ------------------------------------------------------------------
151 // Build all of the file stream objects
152 // ------------------------------------------------------------------
153 this.transport_stream = Components.classes["@mozilla.org/network/file-output-stream;1"]
154 .createInstance(Components.interfaces.nsIFileOutputStream);
156 this.debug_stream = Components.classes["@mozilla.org/network/file-output-stream;1"]
157 .createInstance(Components.interfaces.nsIFileOutputStream);
159 this.error_stream = Components.classes["@mozilla.org/network/file-output-stream;1"]
160 .createInstance(Components.interfaces.nsIFileOutputStream);
162 // ------------------------------------------------------------------
163 // Init all of the streams
164 // use 0x02 | 0x10 to open file for appending.
165 // ------------------------------------------------------------------
166 this.transport_stream.init(transport_file_obj, 0x02 | 0x10 | 0x08, 0664, 0 );
167 this.debug_stream.init( debug_file_obj, 0x02 | 0x10 | 0x08, 0664, 0 );
168 this.error_stream.init( error_file_obj, 0x02 | 0x10 | 0x08, 0664, 0 );
170 Logger.logger = this;
174 /** Internal. Returns a XPCOM nsIFile object for the log file we're interested in */
175 Logger.get_log_file = function( log_name ) {
177 var dirService = Components.classes["@mozilla.org/file/directory_service;1"].
178 getService( Components.interfaces.nsIProperties );
180 logFile = dirService.get( "AChrom", Components.interfaces.nsIFile );
181 logFile.append(myPackageDir);
182 logFile.append("content");
183 logFile.append("log");
184 logFile.append( log_name );
186 if( ! logFile.exists() ) {
187 logFile.create( 0, 0640 );
195 /** Internal. Builds a log message complete with data, etc. */
196 Logger.prototype.build_string = function( message, level ) {
198 if( ! (message && level) ) { return null; }
201 if( level == Logger.ERROR ) { lev = "ERROR"; }
202 if( level == Logger.DEBUG ) { lev = "DEBUG"; }
204 var date = new Date();
205 var year = date.getYear();
208 var month = ""+date.getMonth();
209 if(month.length==1) {month="0"+month;}
210 var day = ""+date.getDate();
211 if(day.length==1) {day="0"+day;}
212 var hour = ""+date.getHours();
213 if(hour.length== 1){hour="0"+hour;}
214 var min = ""+date.getMinutes();
215 if(min.length==1){min="0"+min;}
216 var sec = ""+date.getSeconds();
217 if(sec.length==1){sec="0"+sec;}
218 var mil = ""+date.getMilliseconds();
219 if(mil.length==1){sec="0"+sec;}
221 var date_string = year + "-" + month + "-" + day + " " +
222 hour + ":" + min + ":" + sec + "." + mil;
224 var str_array = message.split('\n');
225 var ret_array = new Array();
226 for( var i in str_array ) {
227 ret_str = "[" + date_string + "] " + lev + " " + str_array[i] + "\n";
228 ret_array.push( ret_str );
231 var line = "-------------------------\n";
232 ret_array.unshift( line );
237 /** Internal. Does the actual writing */
238 Logger.prototype._log = function( data, stream, level ) {
240 if( ! data ) { return; }
242 throw oils_ex_logger( "No file stream open for log message: " + data );
244 if( ! level ) { level = Logger.DEBUG; }
246 if( level > this.log_level ) { return; }
247 var str_array = this.build_string( data, level );
248 if( ! str_array ) { return; }
250 for( var i in str_array ) {
251 if( this.stdout_log > 0 ) { dump( str_array[i] ); }
252 if( this.stdout_log < 2 ) { stream.write( str_array[i], str_array[i].length ); }
255 // write errors to the error log if they were destined for anywhere else
256 if( level == Logger.ERROR && stream != this.error_stream ) {
257 for( var i in str_array ) {
258 if( this.stdout_log > 0 ) { dump( str_array[i] ); }
259 if( this.stdout_log < 2 ) { this.error_stream.write( str_array[i], str_array[i].length ); }
266 /** Writes the message to the error log */
267 Logger.prototype.error = function( message, level ) {
268 this._log( message, this.error_stream, level );
272 /** Writes to the debug log */
273 Logger.prototype.debug = function( message, level ) {
274 this._log( message, this.debug_stream, level );
278 /** Writes to the transport log */
279 Logger.prototype.transport = function( message, level ) {
280 this._log( message, this.transport_stream, level );