2012-02-08 12 views
9

मेरे पास एक node.js स्क्रिप्ट है जो कुछ लिखने के लिए फ़ाइल में लॉगिंग करता है। कुछ घटनाओं पर मैं स्क्रिप्ट के निष्पादन को रोकना चाहता हूं, यानी इसके बाद तुरंत लॉग इन करने और बाहर निकलने की चेतावनी दी जाती है। asyncronious Node.js होने के नाते हमारे जैसे सीधे आगे यह करने के लिए अनुमति नहीं देता:लॉग संदेश के साथ node.js स्क्रिप्ट से बाहर निकलने का सही तरीका क्या है?

#!/usr/local/bin/node 

var fs = require('fs'); 
var stream = fs.createWriteStream('delme.log', { flags: 'a' }); 

stream.write('Something bad happened\n'); 
process.exit(1); 

इसके बजाय संदेश जोड़कर इस स्क्रिप्ट फ़ाइल के साथ कुछ नहीं करता है delme.log के। 'निकास' घटना को संभालना और फ़्लशिंग काम नहीं करता है। एक ही रास्ता अब तक पाया exitting से पहले अंतिम लॉग संदेश लिखने के लिए setTimeout() में process.exit(1) रैप करने के लिए है:

#!/usr/local/bin/node 

var fs = require('fs'); 
var stream = fs.createWriteStream('delme.log', { flags: 'a' }); 

stream.write('Something bad happened\n'); 
setTimeout(function(){ 
    process.exit(1); 
}, 30); 

हालांकि इस रूप में यह स्क्रिप्ट निष्पादन तुरंत बंद नहीं करता है और स्क्रिप्ट कुछ के लिए चल रहे हो जाएगा महत्वपूर्ण घटना के बाद समय हुआ। तो मैं सोच रहा हूं कि एक लॉग संदेश के साथ एक स्क्रिप्ट से बाहर निकलने के अन्य तरीके हैं?

उत्तर

11

चूंकि आप ब्लॉक करना चाहते हैं, और पहले से ही स्ट्रीम का उपयोग कर रहे हैं, तो आप संभवतः स्वयं लेखन को संभालना चाहते हैं।

var data = new Buffer('Something bad happened\n'); 
fs.writeSync(stream.fd, data, 0, data.length, stream.pos); 
process.exit(); 
+0

धन्यवाद! यह setTimeout() कॉल की एक भिन्नता है, जो स्क्रिप्ट निष्पादन को अवरुद्ध नहीं करता है। यदि कोई ऐसा कोड है जिसे अपवाद के बाद निष्पादित नहीं किया जाना चाहिए तो यह पैटर्न चिंता का विषय बन सकता है। – nab

+0

मेरा उत्तर अपडेट किया गया। – fent

+1

मेरे विशेष मामले में मैं लॉगिंग के लिए WriteStream का उपयोग करता हूं, ताकि वास्तविक कॉल लॉग हो। आतंक ('कुछ बुरा हुआ') जो उचित लॉग स्तर के साथ संदेश को कुछ अन्य सामान जोड़ता है। इसलिए लॉगर इंटरफ़ेस को बदले बिना इस स्निपेट को कार्यान्वित करना मुश्किल होगा। मैं अपने समाधान को वैकल्पिक समाधान के रूप में पोस्ट कर रहा हूं। प्रारंभिक प्रश्न पूरी तरह उत्तर दिया गया है। धन्यवाद! – nab

0

मैं सिर्फ इस घटना में stderr के लिए लिख वकालत होगा - उदाहरण के तुच्छ उदाहरण

console.error(util.inspect(exception)); 

और उसके बाद की निगरानी * प्रक्रिया लॉग हठ संभालने दें। मेरी समझ से आजकल आपको नोड निकास से पहले फ्लडिंग नहीं करने के बारे में चिंता करने की ज़रूरत नहीं है (हालांकि मैंने 0.2.x संस्करणों में समस्याग्रस्त विपरीत व्यवहार देखा था)।

(*) की निगरानी प्रक्रिया supervisord, भगवान, monit, हमेशा के लिए, pswatch आदि से अपने पिकअप ले लिए ...

यह भी इस तरह के Heroku और dotcloud आदि के रूप में PaaS प्रदाताओं का उपयोग के लिए एक साफ रास्ता प्रदान करता है ... बुनियादी सुविधाओं के प्रवेश

+1

मैं इसे हल करना पसंद करूंगा (किसी भी तरह) प्रोग्रामकेमी। मेरे पास विभिन्न प्रकार की छोटी दौड़ वाली स्क्रिप्ट हैं।उनमें से कुछ बस एसटीडीईआरआर को चेतावनी देते हैं, फाइल सिस्टम के लिए कुछ लॉग डेटा। मुझे जो चाहिए वह बाहरी सॉफ़्टवेयर पर निर्भर किए बिना एक लॉग संदेश के साथ एक स्क्रिप्ट से बाहर निकलने के लिए एक एकीकृत दृष्टिकोण है। वैसे भी संकेत के लिए धन्यवाद :) – nab

+0

यह flushed नहीं है। – zupa

0

प्रबंध करते हैं मुझे लगता है कि यह सही तरीका है:

process.on('exit', function(){ 
    // You need to use a synchronous, blocking function, here. 
    // Not streams or even console.log, which are non-blocking. 
    console.error('Something bad happened\n'); 
}); 
3

exitting एक एक कोशिश पकड़ ब्लॉक में एक स्क्रिप्ट निष्पादन रैप करने के लिए चाहते हो सकता है पहले एक फाइल करने के लिए सभी लॉग संदेशों को फ्लश करने के लिए। एक बार जब कुछ बुरा हुआ है, यह लॉग ऑन है एक जा रहा है और एक अपवाद है कि बाहरी try जिसमें से यह अतुल्यकालिक रूप से बाहर निकलने के लिए सुरक्षित है द्वारा catched किया जाएगा फेंकता है:

#!/usr/local/bin/node 

var fs = require('fs'); 
var stream = fs.createWriteStream('delme.log', { flags: 'a' }); 
var SOMETHING_BAD = 'Die now'; 

try { 
    // Any code goes here... 
    if (somethingIsBad) { 
    stream.write('Something bad happened\n'); 
    throw new Error(SOMETHING_BAD); 
    } 
} catch (e) { 
    if (e.message === SOMETHING_BAD) { 
    stream.on('drain', function() { 
     process.exit(1); 
    }); 
    } else { 
    throw e; 
    } 
} 
3

बेहतर।

var fs = require('fs'); 
var stream = fs.createWriteStream('delme.log', {flags: 'a'}); 

// Gracefully close log 
process.on('uncaughtException', function() { 
    stream.write('\n'); // Make sure drain event will fire (queue may be empty!) 
    stream.on('drain', function() { 
     process.exit(1); 
    }); 
}); 

// Any code goes here... 
stream.write('Something bad happened\n'); 
throw new Error(SOMETHING_BAD); 

कोशिश कैच ब्लॉक काम करता है, लेकिन यह बदसूरत है। फिर भी, क्रेडिट @nab जाओ, मैंने बस इसे सुंदर बना दिया।

संबंधित मुद्दे

 संबंधित मुद्दे