
Geliştiriciler olarak, bir tür kayıt mekanizması olmadan uygulamalarımızda hata ayıklamak son derece zordur.
Bunun nedeni, günlüklerin kodumuzdaki herhangi bir zaman noktasını yakalayabilmesi ve durumu zaman içinde geriye doğru izlemek için kullanılabilecek uygulama yaşam döngümüzün mevcut durumu hakkında yığın izlerini veya faydalı bilgileri yakalayabilmesidir.
Bu yazıda, JavaScript’te hem nodejs hem de tarayıcı ortamlarında oturum açmanın birkaç uygun taktiğini inceleyeceğiz.
İzleme / Hata Ayıklama
Projelerimiz zamanla büyüdükçe, kodumuz daha karmaşık hale geldikçe kodumuzu izlemek için günlükler oluşturmak giderek daha önemli hale geliyor. Kod karmaşıklığındaki artış, bakımın zorlaşmasına ve kodumuzun okunabilirliğine neden olur.
Beklenmeyen bir davranış oluştuğunda, değişiklikleri izlemenin günlüğe kaydetmeden daha iyi bir yolu yoktur.
Aşağıdaki bir örneğe bakalım:
require('jsdom-global')()
const fetch = require('node-fetch').default
function fetchCats() {
return new Promise((resolve, reject) => {
fetch('https://api.thecatapi.com/v1/images/search?limit=10')
.then((resp) => resp.json())
.then((results) => resolve(results))
.catch(reject)
})
}
class GalleryPages {
constructor(items) {
this.items = items
}
build() {
const wrapper = document.createElement('div')
for (const item of this.items) {
const img = document.createElement('img')
img.width = item.width
img.height = item.height
img.src = item.src
wrapper.appendChild(img)
}
return wrapper
}
}
fetchCats()
.then((cats) => {
return cats.map((cat) => ({
src: cat.url,
width: cat.width,
height: cat.height,
}))
})
.then((cats) => {
const createPage = (child) => {
const container = document.createElement('div')
container.style.width = '250px'
container.style.maxHeight = '250px'
container.style.border = '1px solid magenta'
container.style.margin = '15px 0px'
container.style.position = 'relative'
container.style.overflowX = 'hidden'
container.style.display = 'inline-block'
container.appendChild(child)
document.body.appendChild(container)
return container
}
let elements = []
let cat = cats[cats.length - 1]
while (cats.length) {
const page = new GalleryPages([cat])
elements.push(createPage(page.build()))
cat = cats.pop()
}
return elements
})
.catch((error) => console.error(error))
Beklediğimiz davranış, getirilen her kedi görüntüsü için tek bir öğe içeren yeni bir öğe oluşturmamızdır. img
sonunda “galeri benzeri” bir görünümde gruplandırılacak olan öğe. İstemcide görüntülenirken her resim görsel olarak aynı boyutta gösterilmelidir ve her resim farklı olmalıdır:
Ancak ilk iki resim kopyadır. Kodumuza basit kaydediciler yerleştirerek, hatanın nerede başladığını tam olarak belirlemek için bir kısayol sağlar:
{
src: "https://cdn2.thecatapi.com/images/XT3M3LXmE.jpg",
width: 259,
height: 194
}
{
src: "https://cdn2.thecatapi.com/images/XT3M3LXmE.jpg",
width: 259,
height: 194
}
{
src: "https://cdn2.thecatapi.com/images/yeauSxGXb.jpg",
width: 1500,
height: 1124
}
{
src: "https://cdn2.thecatapi.com/images/dfn.jpg",
width: 450,
height: 569
}
{
src: "https://cdn2.thecatapi.com/images/bl9.jpg",
width: 468,
height: 498
}
{
src: "https://cdn2.thecatapi.com/images/bba.jpg",
width: 500,
height: 333
}
{
src: "https://cdn2.thecatapi.com/images/a88.jpg",
width: 1200,
height: 930
}
{
src: "https://cdn2.thecatapi.com/images/a6s.jpg",
width: 450,
height: 300
}
{
src: "https://cdn2.thecatapi.com/images/9tb.jpg",
width: 612,
height: 612
}
{
src: "https://cdn2.thecatapi.com/images/2lv.png",
width: 500,
height: 333
}
İlk iki nesne aynıdır, böylece for döngümüzün nasıl başladığına hemen bakabiliriz:
Artık mesele apaçık ortaya çıkıyor. Her döngü, bir nesne ile başlamayı bekler. pulled
diziden. Her döngü, dizinin mutasyona uğramış olmasını bekler, bu nedenle diziyi değiştirmemiz gerekir:
Verim
Uygulamalarımızın rekabetçi kalmasını istiyorsak, modern uygulamalarda performans en önemli endişemizdir. Geliştiriciler olarak kullanıcılarımızı mutlu etmek bizim sorumluluğumuzdur ve her şey kodla başlar. kullanarak console
performansı kodumuzun farklı bölümlerinde kaydedebiliriz.
Analiz
Günlükler beklediğimizden çok daha kullanışlıdır. Kodumuzun tamamına rastgele günlükler yerleştirmek bile bize uygulamamızı geliştirmek için kullanabileceğimiz bilgiler verir.
Aşağıdaki gibi şeyleri bulmak için günlük bilgilerimizi kullanabiliriz:
- Yinelenen istekler
- Bellek sızıntıları
- gereksiz değişkenler
- yazım hataları
- Bize todoları tekrar ziyaret etmeyi hatırlatıyor
- İzleme işlevi çağrıları
- Beklenmeyen davranış
Liste devam ediyor.
Önemli Günlüğe Kaydetme Yöntemleri
console.assert
bir iddia başarısız olursa veya başarısız olursa konsola hata mesajları yazmak için kullanışlıdır (genel olarak işlevlerimizde girişleri veya çıktıları doğrulamak için kullanılır) false
. Aksi takdirde hiçbir şey olmayacak. Bu, jenerik ile karşılaştırıldığında bir tür “tembel yükleme” hissi sağlar. console.log
bu da daha fazla bellek kullanımından kaçınmayı kolaylaştırır.
console.clear
konsolu temizlemek için kullanılabilir. Bu, çok fazla günlüğünüz olduğunu fark ettiğiniz ve konsolda gördüğünüz ilk mesajın doğrudan işlevden geldiğinden emin olmak için hata ayıkladığınız bir işlevin hemen önüne yerleştirmek istediğiniz durumlarla karşılaştığınızda yararlıdır. Bu, samanlıkta o iğneyi bulmak için gereksiz yere yukarı ve aşağı kaydırmayı önlemeye yardımcı olur.
console.error
mesajların konsola kaydedilmesine de yardımcı olabilir, ancak tarayıcı konsolunda kırmızı arka planda olmaları nedeniyle hata gibi görünen mesajları görüntüler. Çoğu durumda bu yeterlidir. Ancak yine de daha gösterişli bir yol seçeceğimiz bazı durumlar var: console.log('%c"obj" is not an object', 'color:red;font-weight:400', obj)
hata mesajlarını görüntülemek için
console.debug
mesajları konsola “ayrıntılı” düzeyde verir. Kitaplıklar, kullandıkları kitaplıktaki başlığın altındaki teknik ayrıntılara daha derinden inmek isteyen geliştiriciler için daha fazla teknik bilgi kaydetmek için bu yöntemi kullanır.
console.dir
görüntüleyebilmenin yanı sıra konsola herhangi bir şey görüntülemek için kullanılabilir tüm konsola nesnelerin özellikleri (konfigüre edilebilir depth
seçenek). Tarayıcıda kullanılıyorsa, kullandığımız nesneler console.dir
olabilir etkileşimli bunları genişletme/daraltma yeteneğine sahipken özellikleri/yöntemleri tıklayabileceğimiz yer:
console.group
ve console.groupEnd
konsoldaki “gruplama” efektini simüle ederek, her satırın girintili olabileceği sarılmış bir “kapsayıcı” içine birden çok günlüğü sarmak için kullanılabilir:
const obj = {
myProfile: {
firstName: 'Kelly',
lastName: 'Vaughn',
age: 31,
},
myFavoriteFood: {
fruits: ['strawberry', 'raspberry'],
meat: ['steak'],
},
}
console.group('hello')
console.log(obj.myProfile.firstName)
console.log(obj.myProfile.lastName)
console.log(obj.myFavoriteFood)
console.log(obj.myProfile.age)
console.groupEnd()
ilginç bulduğum şey console.group
gerekirse, altta yatan mesajları yerleştirmek/girinti yapmak için birden çok kez kullanabilmemizdir:
console.group('')
console.group('hello')
console.log(obj.myProfile.firstName)
console.log(obj.myProfile.lastName)
console.group('')
console.group('hello')
console.group('')
console.log(obj.myFavoriteFood)
console.log(obj.myProfile.age)
console.group('')
console.group('')
console.groupEnd()
taktikler
Bazen kendimizi fazla kaptırabilir ve günlüğe kaydedebiliriz. fazla çok bilgi. Bu etkiler çalışma zamanı performansı özellikle günlüklerimize büyük nesneler eklediğimizde.
Günlüğe kaydetme, NodeJS’de çok kullanışlıdır. Ama öyle zamanlar var ki yararlı değil. Ancak, bizim için yararlı olmayan bu günlüklerden bazılarını yapmamız için fırsatlar da var. faydalı olmak.
Aşağıdaki örneğe bakalım:
class Profile {
#firstName
#lastName
#familyMembers
constructor(firstName, lastName) {
this.#firstName = firstName
this.#lastName = lastName
this.#familyMembers = []
}
get firstName() {
return this.#firstName
}
get lastName() {
return this.#lastName
}
get fullName() {
return `${this.firstName} ${this.lastName}`
}
addFamilyMember(profile) {
this.#familyMembers.push(profile)
}
}
Örneklerini oluşturduğumuzda Profile
ve her örneği konsola kaydedin, aşağıdaki gibi yararlı bilgileri görmek istiyoruz firstName
, lastName
, fullName
ve tüm familyMembers
çıktıda.
Ama olan şu ki, konsolda gösterildiklerinde bu bize verilen bilgi türüdür:
const myProfile = new Profile('Kelly', 'Gonzalez')
console.log(myProfile)
Peki bu çıktıyı nasıl faydalı bilgiler haline getirebiliriz? Neyse ki NodeJS bizim için yararlı bir yol sağlıyor. çıktıyı özelleştir nesnelerin.
Inspect
(Önerilen: Genel bir Kullanıcı Snippet’i oluşturun)
Konsoldaki nesnelerin çıktısını özelleştirmek için bir Symbol
değer ile "nodejs.util.inspect.custom"
şöyle:
class Profile {
#firstName
#lastName
#familyMembers;
[Symbol.for('nodejs.util.inspect.custom')]() {
return this.toJSON()
}
constructor(firstName, lastName) {
this.#firstName = firstName
this.#lastName = lastName
this.#familyMembers = []
}
get firstName() {
return this.#firstName
}
get lastName() {
return this.#lastName
}
get fullName() {
return `${this.firstName} ${this.lastName}`
}
get familyMembers() {
return this.#familyMembers
}
addFamilyMember(profile) {
this.#familyMembers.push(profile)
}
toJSON() {
return {
firstName: this.firstName,
lastName: this.lastName,
fullName: this.fullName,
familyMembers: this.familyMembers.map((profile) => profile.toJSON()),
totalFamilyMembers: this.familyMembers.length,
}
}
}
const myProfile = new Profile('Kelly', 'Gonzalez')
const lisa = new Profile('Lisa', 'Gonzalez')
const melon = new Profile('Melon', 'Gonzalez')
const george = new Profile('George', 'Gonzalez')
myProfile.addFamilyMember(lisa)
myProfile.addFamilyMember(melon)
myProfile.addFamilyMember(george)
george.addFamilyMember(new Profile('Terrence', 'Gonzalez'))
console.log(myProfile)
bizim günlüğe kaydetme Profile
konsola örnek, bilgileri istediğimiz şekilde görüntüleyebilir:
{
"firstName": "Kelly",
"lastName": "Gonzalez",
"fullName": "Kelly Gonzalez",
"familyMembers": [
{
"firstName": "Lisa",
"lastName": "Gonzalez",
"fullName": "Lisa Gonzalez",
"familyMembers": [],
"totalFamilyMembers": 0
},
{
"firstName": "Melon",
"lastName": "Gonzalez",
"fullName": "Melon Gonzalez",
"familyMembers": [],
"totalFamilyMembers": 0
},
{
"firstName": "George",
"lastName": "Gonzalez",
"fullName": "George Gonzalez",
"familyMembers": "[Array]",
"totalFamilyMembers": 1
}
],
"totalFamilyMembers": 3
}
Bunu özel bir Kullanıcı Snippet’ine bağlamanızı tavsiye ederim çünkü benim gibiyseniz bunu her seferinde daha fazlası için kullanacaksınız. üretken geliştirme deneyimi.
şunu belirtmekte fayda var [Symbol.for('nodejs.util.inspect.custom')]() {}
ayrıca 3 argümanla birlikte gelir:
[Symbol.for('nodejs.util.inspect.custom')](depth, inspectOptions, inspect) {}
Bu argümanlar hakkında daha fazla bilgi edinebilirsiniz. burada.
Otomasyon
Önceki örneklerimiz güzel çünkü uygulamalarımızı geliştirirken oturum açmayı gerçek zamanlı olarak analiz edebiliyoruz.
Ancak, otomatik komut dosyalarımızda günlükleri görmek istediğimiz zamanlar vardır (örneğin, bir komut dosyasının her 15 dakikada bir veri getirmesi gibi). değil artık çalışma zamanında analiz ediyor.
Varsayılan olarak, Console
NodeJS’deki yapıcı, çıktısını şuraya aktararak terminale giriş yapar stdout
ve stderr
. Aslında bu ikisini çıktısını bir dosya gibi başka bir yere iletecek şekilde yapılandırabiliriz:
const logOutput = fs.createWriteStream(path.join(__dirname, 'logs.json'))
const log = new Console({ stdout: logOutput })
const output = []
output.push(myProfile.familyMembers[0].toJSON())
output.push({ timestamp: new Date().toISOString() })
log.info(JSON.stringify(output, null, 2))
Sonuç:
Pratikte kaydediciler
pino-http [pino] içine girmek için bir kitaplık sağlar ekspresjs http isteklerinden istediğimiz her şeyi günlüğe kaydetmek için bir ara katman yazılımı olarak ardışık düzen isteyin.
dosya akışı döndürücü günlüklerini bir dosyanın içinde tutan sunucu uygulamalarında günlük ara yazılımı ile birlikte kullanılabilir. Tarihe, boyut sınırına veya kombinasyona göre döndürülmesi gereken Ekspres günlüklerin düzenli aralıklarla otomatik olarak döndürülmesini sağlamayı ve eski günlük dosyalarını sayıma veya geçen günlere göre kaldırmayı amaçlar.
günlük güncelleme geliştiricilerin, düğümün özelliklerinden yararlanarak terminalde bir ilerleme çubuğunu veya özelleştirilmiş animasyonları simüle etmelerini sağlar. stdout
ve stderr
(aynı G/Ç Console
kullanır)
kükreme bilgileri hem düğümleri hem de tarayıcı ortamlarını destekleyen JSON olarak günlüğe kaydeder
logdown.js markdown sözdizimini desteklemenin yanı sıra hem düğüm hem de tarayıcı ortamları için bir günlük kaydı mekanizması sağlar.
Çözüm
Ve bu yazının sonu burada bitiyor! Umarım bunu değerli bulmuşsunuzdur ve gelecekte daha fazlasını ararsınız!