@@ -26,6 +26,8 @@ class GhostLogger {
2626 * transports: An array of comma separated transports (e.g. stdout, stderr, geld, loggly, file)
2727 * rotation: Enable or disable file rotation.
2828 * path: Path where to store log files.
29+ * filename: Optional filename template for log files. Supports {env} and {domain} placeholders.
30+ * If not provided, defaults to {domain}_{env} format.
2931 * loggly: Loggly transport configuration.
3032 * elasticsearch: Elasticsearch transport configuration
3133 * gelf: Gelf transport configuration.
@@ -45,6 +47,7 @@ class GhostLogger {
4547 this . logBody = options . logBody || false ;
4648 this . mode = process . env . MODE || options . mode || 'short' ;
4749 this . path = options . path || process . cwd ( ) ;
50+ this . filename = options . filename || '{domain}_{env}' ;
4851 this . loggly = options . loggly || { } ;
4952 this . elasticsearch = options . elasticsearch || { } ;
5053 this . gelf = options . gelf || { } ;
@@ -275,6 +278,30 @@ class GhostLogger {
275278 } ;
276279 }
277280
281+ /**
282+ * @description Sanitize domain for use in filenames.
283+ * Replaces all non-word characters with underscores.
284+ * @param {string } domain - The domain to sanitize
285+ * @returns {string } Sanitized domain safe for filenames
286+ * @example
287+ * sanitizeDomain('http://my-domain.com') // returns 'http___my_domain_com'
288+ */
289+ sanitizeDomain ( domain ) {
290+ return domain . replace ( / [ ^ \w ] / gi, '_' ) ;
291+ }
292+
293+ /**
294+ * @description Replace placeholders in filename template.
295+ * @param {string } template - Filename template with placeholders
296+ * @returns {string } Filename with placeholders replaced
297+ */
298+ // TODO: Expand to other placeholders?
299+ replaceFilenamePlaceholders ( template ) {
300+ return template
301+ . replace ( / { e n v } / g, this . env )
302+ . replace ( / { d o m a i n } / g, this . sanitizeDomain ( this . domain ) ) ;
303+ }
304+
278305 /**
279306 * @description Setup file stream.
280307 *
@@ -283,8 +310,7 @@ class GhostLogger {
283310 * 2. file-all: everything
284311 */
285312 setFileStream ( ) {
286- // e.g. http://my-domain.com --> http___my_domain_com
287- const sanitizedDomain = this . domain . replace ( / [ ^ \w ] / gi, '_' ) ;
313+ const baseFilename = this . replaceFilenamePlaceholders ( this . filename ) ;
288314
289315 // CASE: target log folder does not exist, show warning
290316 if ( ! fs . existsSync ( this . path ) ) {
@@ -296,7 +322,7 @@ class GhostLogger {
296322 if ( this . rotation . useLibrary ) {
297323 const RotatingFileStream = require ( '@tryghost/bunyan-rotating-filestream' ) ;
298324 const rotationConfig = {
299- path : `${ this . path } ${ sanitizedDomain } _ ${ this . env } .log` ,
325+ path : `${ this . path } ${ baseFilename } .log` ,
300326 period : this . rotation . period ,
301327 threshold : this . rotation . threshold ,
302328 totalFiles : this . rotation . count ,
@@ -310,7 +336,7 @@ class GhostLogger {
310336 name : this . name ,
311337 streams : [ {
312338 stream : new RotatingFileStream ( Object . assign ( { } , rotationConfig , {
313- path : `${ this . path } ${ sanitizedDomain } _ ${ this . env } .error.log`
339+ path : `${ this . path } ${ baseFilename } .error.log`
314340 } ) ) ,
315341 level : 'error'
316342 } ] ,
@@ -337,7 +363,7 @@ class GhostLogger {
337363 name : this . name ,
338364 streams : [ {
339365 type : 'rotating-file' ,
340- path : `${ this . path } ${ sanitizedDomain } _ ${ this . env } .error.log` ,
366+ path : `${ this . path } ${ baseFilename } .error.log` ,
341367 period : this . rotation . period ,
342368 count : this . rotation . count ,
343369 level : 'error'
@@ -352,7 +378,7 @@ class GhostLogger {
352378 name : this . name ,
353379 streams : [ {
354380 type : 'rotating-file' ,
355- path : `${ this . path } ${ sanitizedDomain } _ ${ this . env } .log` ,
381+ path : `${ this . path } ${ baseFilename } .log` ,
356382 period : this . rotation . period ,
357383 count : this . rotation . count ,
358384 level : this . level
@@ -367,7 +393,7 @@ class GhostLogger {
367393 log : bunyan . createLogger ( {
368394 name : this . name ,
369395 streams : [ {
370- path : `${ this . path } ${ sanitizedDomain } _ ${ this . env } .error.log` ,
396+ path : `${ this . path } ${ baseFilename } .error.log` ,
371397 level : 'error'
372398 } ] ,
373399 serializers : this . serializers
@@ -379,7 +405,7 @@ class GhostLogger {
379405 log : bunyan . createLogger ( {
380406 name : this . name ,
381407 streams : [ {
382- path : `${ this . path } ${ sanitizedDomain } _ ${ this . env } .log` ,
408+ path : `${ this . path } ${ baseFilename } .log` ,
383409 level : this . level
384410 } ] ,
385411 serializers : this . serializers
0 commit comments