Przejdź do głównej zawartości

Przepływ debugowania CLI

Debugowanie to miejsce gdzie deweloperzy spędzają połowę swojego życia. Ten zagadkowy komunikat błędu o 2 w nocy. Bug, który pojawia się tylko na produkcji. Koszmar “u mnie działa”. Claude Code przekształca debugowanie z frustrującego poszukiwania skarbów w systematyczne śledztwo z detektywem AI u twojego boku.

Scenariusz: Twoje produkcyjne API rzuca sporadyczne błędy 500. Użytkownicy narzekają, monitoring szaleje, a logi błędów pokazują zagadkowy “TypeError: Cannot read property ‘id’ of undefined” gdzieś głęboko w middleware’ze uwierzytelniania. Stack trace obejmuje 15 plików. Od czego w ogóle zacząć?

Okno terminala
# Godziny ręcznego śledztwa
grep -r "Cannot read property 'id'" .
# 47 wyników...
# Dodawanie console.log wszędzie
console.log('TUTAJ 1');
console.log('user:', user);
console.log('TUTAJ 2');
# Deploy na staging, testowanie, powtarzaj
# W końcu znajdziesz problem po 3 godzinach
  1. Skonfiguruj verbose logging
    Okno terminala
    # Włącz tryb debug Claude
    claude --debug
    # Lub ustaw zmienną środowiskową
    export ANTHROPIC_LOG=debug
2. **Skonfiguruj przechwytywanie błędów**
```
> Stwórz helper debugowania który przechwytuje i formatuje błędy
> do analizy. Uwzględnij stack traces, informacje o środowisku,
> i ostatnie wpisy w logach
```
3. **Zainstaluj serwery MCP debugowania**
```bash
# Do analizy logów
claude mcp add logs-analyzer
# Do monitorowania systemu
claude mcp add system-monitor
```
4. **Stwórz komendy debugowania**
Zapisz w `.claude/commands/debug-issue.md`:
```markdown
Przeanalizuj ten błąd systematycznie:
1. Parsuj komunikat błędu i stack trace
2. Zidentyfikuj lokalizację głównej przyczyny
3. Przejdź przez ścieżkę wykonania
4. Znajdź powiązany kod i zależności
5. Zasugeruj konkretne poprawki
6. Stwórz test aby zapobiec regresji
Szczegóły błędu: $ARGUMENTS
```
## Systematyczny przepływ debugowania
### Faza 1: Zbieranie informacji
<CardGrid>
<Card title="Kontekst błędu">
- Pełny komunikat błędu - Kompletny stack trace - Szczegóły środowiska - Ostatnie zmiany w kodzie - Akcje
użytkownika które go wywołują
</Card>
<Card title="Stan systemu">
- Użycie pamięci - Obciążenie CPU - Połączenia z bazą danych - Status usług zewnętrznych - Ostatnie
wdrożenia
</Card>
<Card title="Dane historyczne">
- Kiedy po raz pierwszy się pojawił - Wzorce częstotliwości - Dotknięci użytkownicy - Powiązane błędy -
Poprzednie próby naprawy
</Card>
<Card title="Kontekst kodu">
- Ostatnie commity - Zaktualizowane zależności - Zmiany konfiguracji - Zmodyfikowane feature flags -
Powiązane pull requesty
</Card>
</CardGrid>
### Faza 2: Analiza wspomagana AI
```
> Przeanalizuj ten błąd produkcyjny. Stack trace załączony.
> Zdarza się gdy użytkownicy z wygasłymi sesjami próbują
> uzyskać dostęp do chronionych route'ów. Rozpoczęło się po wczorajszym deploy.
```
Systematyczne podejście Claude:
1. **Parsowanie błędu**
```javascript
// Claude identyfikuje: TypeError w auth.middleware.js:47
// Próba dostępu do user.id gdy user jest null
```
2. **Śledzenie ścieżki wykonania**
```
Request → AuthMiddleware → SessionValidator → UserLoader
Session expired
Returns null
Middleware continues
Accesses null.id → ERROR
```
3. **Identyfikacja głównej przyczyny**
```javascript
// Znaleziono: Race condition między wygaśnięciem sesji a ładowaniem użytkownika
// Sesja wygasa PO walidacji ale PRZED zakończeniem pobierania użytkownika
```
4. **Dostarczenie poprawki**
```javascript
// Przed (buggy):
const session = await validateSession(token);
const user = await loadUser(session.userId);
// Race condition window tutaj!
req.user = user;
// Po (naprawione):
const session = await validateSession(token);
if (!session || session.isExpired()) {
return res.status(401).json({ error: 'Session expired' });
}
const user = await loadUser(session.userId);
if (!user) {
return res.status(401).json({ error: 'User not found' });
}
req.user = user;
```
## Scenariusze debugowania z życia
### Scenariusz 1: Heisenbug
_Bug który znika gdy próbujesz go obserwować._
```
> Mamy bug który pojawia się tylko na produkcji, nigdy w dev.
> Użytkownicy zgłaszają "undefined is not a function" ale nie mogę go odtworzyć.
> Oto logi Sentry i raporty użytkowników.
```
<Tabs>
<TabItem label="Śledztwo Claude">
```javascript
// Claude analizuje różnice między środowiskami
Produkcja: NODE_ENV=production, Zminifikowany kod, Assety z CDN
Development: NODE_ENV=development, Source maps, Lokalne assety
// Odkrywa: Minifikacja zmieniła nazwę funkcji wywoływanej przez string
// W dev: window['calculateTotal']() działa
// W prod: window['a3f']() nie działa (zminifikowana nazwa)
// Rozwiązanie: Skonfiguruj minifier aby zachował nazwy funkcji
terserOptions: {
keep_fnames: true,
mangle: {
reserved: ['calculateTotal', 'validateInput']
}
}
```
</TabItem>
<TabItem label="Strategia zapobiegania">
```javascript
// Claude sugeruje defensive coding
// Zamiast dynamicznych wywołań funkcji:
const functionName = getUserFunction();
window[functionName](); // Kruche!
// Użyj mapy funkcji:
const functions = {
calculateTotal,
validateInput
};
const fn = functions[getUserFunction()];
if (fn) fn();
else console.error('Unknown function');
```
</TabItem>
</Tabs>
### Scenariusz 2: Degradacja wydajności
_Wszystko jest wolne, ale nic nie jest wyraźnie zepsute._
```
> Czasy odpowiedzi naszego API wzrosły z 200ms do 2s w ciągu
> ostatniego tygodnia. Brak oczywistych błędów, wszystko po prostu wolniej.
> CPU i pamięć wyglądają normalnie. Pomóż mi znaleźć wąskie gardło.
```
Debugowanie wydajności przez Claude:
1. **Analiza ostatnich zmian**
```
> Pokaż mi wszystkie zmiany kodu z ostatniego tygodnia które mogłyby
> wpłynąć na wydajność. Skup się na zapytaniach bazodanowych, pętlach,
> i wywołaniach zewnętrznych API.
```
2. **Profilowanie krytycznych ścieżek**
```javascript
// Claude dodaje instrumentację czasową
const trace = async (name, fn) => {
const start = performance.now();
try {
const result = await fn();
console.log(`${name}: ${performance.now() - start}ms`);
return result;
} catch (error) {
console.error(`${name} failed:`, error);
throw error;
}
};
// Opakowuje kluczowe operacje
const user = await trace('loadUser', () => loadUser(id));
const perms = await trace('checkPerms', () => checkPermissions(user));
```
3. **Identyfikacja wąskiego gardła**
```sql
-- Claude znajduje: Nowa kontrola uprawnień uruchamia to zapytanie
SELECT * FROM permissions p
JOIN roles r ON p.role_id = r.id
JOIN user_roles ur ON r.id = ur.role_id
WHERE ur.user_id = ? AND p.resource = ?
-- Brakuje indeksu na (user_id, resource)!
```
4. **Optymalizacja**
```sql
-- Dodaj indeks złożony
CREATE INDEX idx_user_resource
ON permissions(user_id, resource);
-- Czas odpowiedzi: 2000ms → 180ms
```
### Scenariusz 3: Wyciek pamięci
_Twoja usługa Node.js crashuje co 6 godzin z "JavaScript heap out of memory"._
```
> Produkcja ciągle crashuje z błędami OOM. Użycie pamięci
> rośnie powoli przez godziny. Oto diff snapshotu heap.
> Pomóż mi znaleźć co przecieka.
```
<Aside type="tip">
Przy debugowaniu wycieków pamięci, dostarcz Claude: - Diffy snapshotów heap - Wykresy użycia pamięci -
Ostatnie zmiany w kodzie - Integracje usług zewnętrznych
</Aside>
Śledztwo wycieku pamięci przez Claude:
```javascript
// Claude analizuje snapshot heap, znajduje rosnącą tablicę
// Winowajca: Event listenery nie są czyszczone
class OrderMonitor {
constructor() {
// Listenery dodawane przy każdym request!
eventBus.on('order.created', this.handleOrder);
}
handleOrder = (order) => {
this.orders.push(order); // Nigdy nie czyszczone!
};
}
// Poprawiona wersja:
class OrderMonitor {
constructor() {
this.handleOrder = this.handleOrder.bind(this);
eventBus.on('order.created', this.handleOrder);
}
cleanup() {
eventBus.off('order.created', this.handleOrder);
this.orders = [];
}
handleOrder(order) {
this.orders.push(order);
// Przetwarzaj i czyść stare zamówienia
if (this.orders.length > 100) {
this.processOrders(this.orders.splice(0, 50));
}
}
}
```
## Zaawansowane techniki debugowania
### Debugowanie systemów rozproszonych
_Gdy bug obejmuje wiele usług._
```
> Użytkownicy zgłaszają że zamówienia losowo się nie powiodą. Błąd pojawia się w
> usłudze zamówień, ale może dotyczyć usługi płatności, zapasów,
> lub notyfikacji. Jak to wyśledzić?
```
Claude implementuje distributed tracing:
```javascript
// Dodaj correlation ID
const correlationId = req.headers['x-correlation-id'] || uuid();
// Przekazuj przez wszystkie wywołania usług
const payment = await paymentService.charge({
...paymentData,
headers: { 'x-correlation-id': correlationId }
});
// Agreguj logi
> Przeszukaj wszystkie logi usług dla correlation ID abc-123-def
> Pokaż mi kompletny przepływ requestu i gdzie się nie powiódł
```
### Debugowanie podróży w czasie
```
> Bug zdarzył się 3 godziny temu na produkcji. User ID 12345
> nie mógł ukończyć checkout. Czy możemy zrekonstruować co się stało?
```
Claude tworzy maszynę czasu debugowania:
```javascript
// Rekonstruuj stan w określonym czasie
const timeTravel = async (userId, timestamp) => {
const logs = await getLogs({ userId, time: timestamp });
const dbState = await getDbSnapshot(timestamp);
const events = await getEvents({ userId, before: timestamp });
return {
userState: dbState.users.find(u => u.id === userId),
recentActions: events.slice(-10),
systemLoad: logs.filter(l => l.type === 'performance'),
errors: logs.filter(l => l.level === 'error')
};
};
// Claude analizuje zrekonstruowany stan
> O 14:23:45, użytkownik 12345 miał wygasłą metodę płatności.
> Usługa płatności zwróciła błąd ale usługa zamówień
> nie obsłużyła go poprawnie, zostawiając zamówienie w stanie limbo.
```
## Automatyzacja debugowania
### Samonaprawiające się systemy
```
> Stwórz system który automatycznie wykrywa i naprawia
> częste błędy bez interwencji człowieka
```
Claude implementuje:
```javascript
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
const selfHeal = {
// Pattern matching dla znanych problemów
patterns: [
{
error: /Cannot read property .* of undefined/,
action: async (context) => {
// Dodaj null checks do problematycznej linii
const file = context.stack.getFileName();
const line = context.stack.getLineNumber();
// Użyj Claude Code CLI aby naprawić problem
const prompt = `Add null check before property access at ${file}:${line}`;
await execAsync(`claude -p "${prompt}" --cwd .`);
},
},
{
error: /ECONNREFUSED.*redis/,
action: async () => {
// Restartuj połączenie Redis
await redis.disconnect();
await redis.connect();
},
},
],
monitor: async (error) => {
const pattern = this.patterns.find((p) => p.error.test(error.message));
if (pattern) {
console.log('Self-healing:', error.message);
await pattern.action(error);
}
},
};
```
### Debugowanie predykcyjne
```
> Przeanalizuj nasze wzorce błędów i przewidź co może się zepsuć następne
```
Claude dostarcza analizę predykcyjną:
```javascript
// Analizuje trendy błędów
const predictions = await analyzeTrends({
errorLogs: last30Days,
deployments: recentDeploys,
codeChanges: recentCommits
});
// Wynik:
{
highRisk: [
{
component: "PaymentService",
reason: "Error rate increasing 15% daily",
prediction: "Likely to fail within 48 hours",
preventiveAction: "Scale payment service, check API limits"
}
],
patterns: [
{
correlation: "Errors spike every Monday 9 AM",
cause: "Weekly report generation overloads database",
solution: "Implement query caching or move to off-hours"
}
]
}
```
## Najlepsze praktyki debugowania
### 1. Strukturalne logowanie
```javascript
// Format logów przyjazny Claude
logger.error({
message: 'Payment processing failed',
error: error.stack,
context: {
userId: user.id,
orderId: order.id,
amount: payment.amount,
provider: payment.provider,
},
metadata: {
correlationId,
timestamp: new Date().toISOString(),
environment: process.env.NODE_ENV,
},
});
```
### 2. Granice błędów
```javascript
// Graceful error handling
const debugWrapper =
(fn) =>
async (...args) => {
const start = Date.now();
const context = { fn: fn.name, args, start };
try {
const result = await fn(...args);
logger.debug({ ...context, duration: Date.now() - start });
return result;
} catch (error) {
logger.error({ ...context, error: error.stack });
// Pozwól Claude analizować natychmiast
if (process.env.AUTO_DEBUG) {
// Użyj Claude Code CLI do automatycznego debugowania
const debugPrompt = `Debug this error: ${error.message}\nContext: ${JSON.stringify(context)}`;
await execAsync(`claude -p "${debugPrompt}" --output-format json`);
}
throw error;
}
};
```
### 3. Artefakty debugowania
Zawsze zapisuj kontekst debugowania:
```
> Po debugowaniu tego problemu, stwórz:
> 1. Runbook dla podobnych błędów
> 2. Test case aby zapobiec regresji
> 3. Alert monitoringu do wczesnego wykrywania
> 4. Dokumentację głównej przyczyny
```
## Narzędzia i integracje
### Analiza logów z Claude
```bash
# Przekieruj logi bezpośrednio do Claude
tail -f app.log | claude -p "Watch for anomalies and alert me"
# Analizuj logi historyczne
cat errors.log | claude -p "Find patterns in these errors"
# Debugowanie w czasie rzeczywistym
journalctl -f -u myapp | claude -p "Debug any errors in real-time"
```
### Integracja z monitoringiem
```javascript
// Integracja Sentry z Claude Code CLI
const { exec } = require('child_process');
const { promisify } = require('util');
const fs = require('fs').promises;
const execAsync = promisify(exec);
Sentry.init({
beforeSend: async (event) => {
// Analizuj złożone błędy za pomocą Claude Code CLI
if (event.level === 'error' && event.complexity === 'high') {
try {
// Przygotuj kontekst błędu do analizy
const errorContext = {
error: event.exception,
stackTrace: event.stacktrace,
context: Sentry.getContext(),
breadcrumbs: event.breadcrumbs,
};
// Zapisz kontekst do pliku dla analizy Claude Code
await fs.writeFile('/tmp/error-context.json', JSON.stringify(errorContext, null, 2));
// Wykonaj Claude Code CLI dla analizy błędu
const { stdout } = await execAsync(
`claude "Przeanalizuj ten błąd i zasugeruj naprawę" --file /tmp/error-context.json --json`
);
const analysis = JSON.parse(stdout);
// Dodaj analizę Claude do zdarzenia Sentry
event.extra = event.extra || {};
event.extra.claudeAnalysis = analysis;
// Wyczyść plik tymczasowy
await fs.unlink('/tmp/error-context.json');
} catch (error) {
console.error('Nie udało się przeanalizować błędu za pomocą Claude Code:', error);
}
}
return event;
},
});
```
## Powiązane lekcje
<LinkCard
title="Strategie testowania"
description="Zapobiegaj bugom zanim się pojawią dzięki kompleksowemu testowaniu"
href="/pl/claude-code/lessons/testing"
/>
<LinkCard
title="Analiza wydajności"
description="Głębokie nurkowanie w debugowanie i optymalizację wydajności"
href="/pl/claude-code/lessons/performance"
/>
<LinkCard
title="Odzyskiwanie po błędach"
description="Buduj odporne systemy które gracefully radzą sobie z awariami"
href="/pl/claude-code/lessons/error-recovery"
/>
## Następne kroki
Nauczyłeś się jak przekształcić debugowanie z czasochłonnego zajęcia w systematyczny proces. Z Claude Code jako twoim partnerem debugowania, możesz stawić czoła najbardziej złożonym problemom z pewnością siebie.
Pamiętaj: Świetne debugowanie nie polega na byciu sprytnym - to kwestia bycia systematycznym. Pozwól Claude obsługiwać dopasowywanie wzorców i analizę kodu, podczas gdy ty skupiasz się na zrozumieniu problemu i projektowaniu rozwiązania. Razem będziecie eliminować bugi szybciej niż kiedykolwiek wcześniej.