← All Articles

Shopify आपको लॉग फाइलें नहीं देगा। Cloudflare (या किसी भी Edge CDN) से उन्हें प्राप्त करने की पूरी तकनीकी गाइड।

Shopify स्टोर के लिए Cloudflare CDN रिक्वेस्ट लॉगिंग आर्किटेक्चर

ई-कॉमर्स में एक बड़ी अंधी जगह अब हल हो गई है

जब से Shopify लॉन्च हुआ है, इस प्लेटफॉर्म ने रॉ सर्वर लॉग को स्टोर मालिकों की पहुंच से पूरी तरह बाहर रखा है। आपको कन्वर्शन फ़नल और बिक्री रिपोर्ट मिलती हैं। लेकिन जो चीज़ आपको नहीं मिलती, वह है वो एकमात्र चीज़ जो वास्तव में बताती है कि आपके सर्वर पर क्या आ रहा है: HTTP रिक्वेस्ट लॉग।

कई सालों तक, यह एक छोटी सी परेशानी थी। जब आपके पास पेज व्यू और कन्वर्शन रेट हैं तो रॉ लॉग की कौन परवाह करता है? Google Analytics आपके मानव विज़िटर्स को ट्रैक करता है। आपका विज्ञापन प्लेटफॉर्म आपके कैंपेन ट्रैक करता है। सब ठीक है।

फिर AI आया।

ChatGPT, Claude, Perplexity, Google AI Overviews, Microsoft Copilot - ये सभी अभी आपके स्टोर पर बॉट भेज रहे हैं। कुछ ट्रेनिंग डेटा बनाने के लिए आपके पेज क्रॉल कर रहे हैं। अन्य ग्राहक के सवाल का जवाब देने के लिए रियल टाइम में आपकी प्रोडक्ट सामग्री फ़ेच कर रहे हैं। और सबसे बड़ी बात? Google Analytics जैसे पारंपरिक एनालिटिक्स टूल इनमें से कुछ भी नहीं देख सकते। वे क्लाइंट-साइड JavaScript पर निर्भर हैं जिसे बॉट कभी एक्सीक्यूट नहीं करते। आपके स्टोर के साथ AI की अधिकांश बातचीत आपके लिए अदृश्य है।

यह ई-कॉमर्स में नई अंधी जगह है। AI बॉट आपकी ट्रैकिंग स्क्रिप्ट नहीं चलाते। वे कुकीज़ स्वीकार नहीं करते। वे आपकी GA4 रिपोर्ट में दिखाई नहीं देते। लेकिन वे निश्चित रूप से आपके प्रोडक्ट पेज पढ़ रहे हैं, आपके विवरणों को AI-जनित उत्तरों में खींच रहे हैं, और यह आकार दे रहे हैं कि ग्राहक कभी आपके ब्रांड की खोज करें या नहीं।

साइट मालिकों को सर्वर-साइड ट्रैकिंग, बॉट वर्गीकरण, और IP सत्यापन के माध्यम से AI क्रॉलर गतिविधि और AI-जनित रेफरल को समझने में मदद करने के लिए “एजेंट एनालिटिक्स” पर केंद्रित नए टूल उभर रहे हैं। उद्योग यह पहचानता है कि पुराना क्लाइंट-साइड एनालिटिक्स मॉडल AI-फर्स्ट कंटेंट डिस्कवरी के युग के लिए मौलिक रूप से टूटा हुआ है। इसीलिए हमने WISLR AI Visibility Dashboard बनाया - ब्रांडों को यह स्पष्ट तस्वीर देने के लिए कि AI प्लेटफॉर्म उनकी सामग्री के साथ कैसे बातचीत कर रहे हैं, क्रॉल रेट से लेकर फ़ेच रिक्वेस्ट और AI-संचालित रेफरल ट्रैफिक तक।

लेकिन अगर आप Shopify पर हैं, तो आपके पास एक अनोखी समस्या है: आप सर्वर को नियंत्रित नहीं करते। आप सीधे सर्वर-साइड ट्रैकिंग इंस्टॉल नहीं कर सकते। आप अपने एक्सेस लॉग टेल नहीं कर सकते। आप GPTBot के लिए grep नहीं कर सकते। Shopify का बुनियादी ढांचा एक ब्लैक बॉक्स है, और उन्होंने इसे खोलने की कोई जल्दबाजी नहीं दिखाई है।

अब और नहीं। यहां बताया गया है कि अपने लॉग कैसे वापस पाएं।

यह गाइड आपको Cloudflare का उपयोग करके Shopify स्टोर के लिए अपनी खुद की पूर्ण रिक्वेस्ट लॉगिंग पाइपलाइन बनाने की प्रक्रिया बताती है। हर HTTP रिक्वेस्ट। पूरा भौगोलिक डेटा। प्रदर्शन मेट्रिक्स। और सबसे महत्वपूर्ण, पूर्ण बॉट पहचान और वर्गीकरण, ताकि आप अंततः देख सकें कि कौन से AI सिस्टम आपके स्टोर पर आ रहे हैं, कितनी बार, और कौन से पेज उन्हें रुचिकर लगते हैं।


Shopify के लिए Cloudflare रिक्वेस्ट लॉगिंग कैसे काम करती है?

 Visitor requests your Shopify store
         │
         ▼
 Cloudflare CDN (your domain proxied through Cloudflare)
         │
         ▼
 Cloudflare Worker (runs on every request)
    ├──→ Passes request through to Shopify origin (visitor gets normal response)
    └──→ POSTs a JSON log entry to your log receiver (non-blocking, via ctx.waitUntil)
              │
              ▼
         Cloudflare Tunnel
         (CNAME on your domain → tunnel → localhost on your server)
              │
              ▼
         Node.js HTTP Receiver (localhost:9090)
              │
              ▼
         JSON log files written to disk

कोई पोर्ट सार्वजनिक रूप से एक्सपोज़ नहीं किया जाता। Cloudflare Tunnel केवल आउटबाउंड कनेक्शन के माध्यम से Cloudflare के एज से आपके सर्वर तक सुरक्षित ट्रांसपोर्ट को संभालता है।


Shopify रिक्वेस्ट लॉगिंग सेट अप करने के लिए आपको क्या चाहिए?

  • Cloudflare के माध्यम से प्रॉक्सी किए गए कस्टम डोमेन वाला एक Shopify स्टोर (ऑरेंज क्लाउड सक्षम)
  • लॉग प्राप्त करने के लिए एक सर्वर
  • सर्वर पर Node.js इंस्टॉल होना चाहिए
  • Workers सक्षम Cloudflare अकाउंट
  • Wrangler CLI इंस्टॉल (npm install -g wrangler)
  • सर्वर पर Cloudflared इंस्टॉल

चरण 1: Cloudflare Worker बनाएं

Worker आपके डोमेन पर हर रिक्वेस्ट को इंटरसेप्ट करता है, उसे Shopify को प्रॉक्सी करता है, और असिंक्रोनस रूप से एक लॉग एंट्री आपके रिसीवर को भेजता है।

1a. Worker सोर्स (cloudflare-worker.js)

/**
 * Shopify Request Logger
 *
 * Cloudflare Worker that:
 * 1. Logs ALL requests to a self-hosted log receiver (via Cloudflare Tunnel)
 * 2. Optionally logs detailed bot request data to a database
 */

// ============================================
// CONFIG - update these for your setup
// ============================================
const INGEST_URL = 'https://log-collector.yourdomain.com/collect';  // Your tunnel hostname
const INGEST_API_KEY = process.env.INGEST_API_KEY || '';          // Set as Worker secret

// ============================================
// BOT DETECTION PATTERNS
// ============================================
const BOT_PATTERNS = {
  // AI realtime fetchers (user-triggered queries)
  'ChatGPT-User':    { pattern: /ChatGPT-User/i,    type: 'realtime' },
  'Perplexity-User': { pattern: /Perplexity-User/i,  type: 'realtime' },
  // Add your own patterns here for other AI bots

  // Search engine crawlers
  'Googlebot':       { pattern: /Googlebot/i,        type: 'crawler' },
  'Bingbot':         { pattern: /bingbot/i,          type: 'crawler' },

  // Social link preview bots
  'FacebookBot':     { pattern: /facebookexternalhit/i, type: 'preview' },
  'LinkedInBot':     { pattern: /LinkedInBot/i,      type: 'preview' },
};

function identifyBot(userAgent) {
  if (!userAgent) return { name: 'unknown', type: 'unknown' };
  for (const [name, config] of Object.entries(BOT_PATTERNS)) {
    if (config.pattern.test(userAgent)) return { name, type: config.type };
  }
  return { name: 'other', type: 'unknown' };
}

function isKnownBot(userAgent) {
  if (!userAgent) return false;
  return Object.values(BOT_PATTERNS).some(config => config.pattern.test(userAgent));
}

async function logToReceiver(request, env, perfData = {}) {
  const url = new URL(request.url);
  const cf = request.cf || {};
  const bot = identifyBot(request.headers.get('user-agent') || '');

  const logEntry = {
    // Request basics
    timestamp:        new Date().toISOString(),
    method:           request.method,
    url:              request.url,
    path:             url.pathname,
    host:             url.hostname,
    userAgent:        request.headers.get('user-agent') || '',
    ip:               request.headers.get('cf-connecting-ip') || '',
    referer:          request.headers.get('referer') || '',
    cfRay:            request.headers.get('cf-ray') || '',

    // Bot classification
    botName:          bot.name,
    botType:          bot.type,

    // Cloudflare geo data
    country:          cf.country || '',
    region:           cf.region || '',
    city:             cf.city || '',
    postalCode:       cf.postalCode || '',
    latitude:         cf.latitude || '',
    longitude:        cf.longitude || '',
    timezone:         cf.timezone || '',
    continent:        cf.continent || '',

    // Network info
    asn:              cf.asn || '',
    asOrganization:   cf.asOrganization || '',
    colo:             cf.colo || '',
    httpProtocol:     cf.httpProtocol || '',
    tlsVersion:       cf.tlsVersion || '',

    // Client hints (helps detect headless browsers)
    secChUa:          request.headers.get('sec-ch-ua') || '',
    secChUaMobile:    request.headers.get('sec-ch-ua-mobile') || '',
    secChUaPlatform:  request.headers.get('sec-ch-ua-platform') || '',

    // Fetch metadata (helps detect programmatic requests)
    secFetchDest:     request.headers.get('sec-fetch-dest') || '',
    secFetchMode:     request.headers.get('sec-fetch-mode') || '',
    secFetchSite:     request.headers.get('sec-fetch-site') || '',

    // Performance metrics
    edgeStartTimestamp:       perfData.startTime || '',
    edgeEndTimestamp:         perfData.endTime || '',
    edgeTimeToFirstByteMs:   perfData.ttfbMs ?? '',
    clientTcpRttMs:          cf.clientTcpRtt ?? '',
    cacheCacheStatus:        perfData.cacheStatus || '',
    originResponseStatus:    perfData.responseStatus ?? '',
  };

  try {
    await fetch(INGEST_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': env.INGEST_API_KEY,
      },
      body: JSON.stringify({ logs: [logEntry] }),
    });
  } catch (e) {
    console.error(`Log ingest failed: ${e.message}`);
  }
}

export default {
  async fetch(request, env, ctx) {
    const startTime = Date.now();
    const url = new URL(request.url);

    // Avoid infinite loop - skip logging for your ingest hostname
    if (url.hostname === 'log-collector.yourdomain.com') {
      return fetch(request);
    }

    // Fetch the origin response (Shopify)
    const response = await fetch(request);
    const endTime = Date.now();

    // Ship log entry asynchronously (does not delay the response)
    ctx.waitUntil(logToReceiver(request, env, {
      startTime,
      endTime,
      ttfbMs: endTime - startTime,
      cacheStatus: response.headers.get('cf-cache-status') || '',
      responseStatus: response.status,
    }));

    return response;
  }
};

1b. Wrangler कॉन्फ़िगरेशन (wrangler.toml)

name = "shopify-request-logger"
main = "cloudflare-worker.js"
compatibility_date = "2024-01-01"

routes = [
  { pattern = "www.yourdomain.com/*", zone_name = "yourdomain.com" }
]

www.yourdomain.com को अपने Shopify स्टोर के कस्टम डोमेन से बदलें।

1c. Worker Secrets सेट करें

wrangler secret put INGEST_API_KEY
# Paste your generated API key when prompted

1d. डिप्लॉय करें

npx wrangler deploy

चरण 2: अपने सर्वर पर लॉग रिसीवर सेट करें

एक न्यूनतम Node.js HTTP सर्वर जो लॉग बैचेस स्वीकार करता है और उन्हें डिस्क पर लिखता है।

2a. रिसीवर स्क्रिप्ट (receive-logs.js)

const http = require('http');
const fs = require('fs');
const path = require('path');

const PORT = 9090;
const API_KEY = process.env.LOG_API_KEY;
const LOG_DIR = '/var/log/cdn-requests';  // Choose your log directory

if (!API_KEY) {
  console.error('LOG_API_KEY environment variable is required');
  process.exit(1);
}

// Ensure log directory exists
fs.mkdirSync(LOG_DIR, { recursive: true });

const server = http.createServer((req, res) => {
  // Health check
  if (req.method === 'GET' && req.url === '/status') {
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ status: 'ok' }));
    return;
  }

  // Log ingest endpoint
  if (req.method === 'POST' && req.url === '/collect') {
    const apiKey = req.headers['x-api-key'];
    if (apiKey !== API_KEY) {
      res.writeHead(401, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ error: 'unauthorized' }));
      return;
    }

    let body = '';
    let size = 0;
    const MAX_BODY = 10 * 1024 * 1024; // 10MB limit

    req.on('data', chunk => {
      size += chunk.length;
      if (size > MAX_BODY) {
        res.writeHead(413, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ error: 'payload too large' }));
        req.destroy();
        return;
      }
      body += chunk;
    });

    req.on('end', () => {
      try {
        JSON.parse(body); // Validate JSON
      } catch (e) {
        res.writeHead(400, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ error: 'invalid JSON' }));
        return;
      }

      const filename = `logs-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.json`;
      const filepath = path.join(LOG_DIR, filename);

      fs.writeFile(filepath, body, err => {
        if (err) {
          console.error(`Write failed: ${err.message}`);
          res.writeHead(500, { 'Content-Type': 'application/json' });
          res.end(JSON.stringify({ error: 'write failed' }));
          return;
        }
        console.log(`Wrote ${filename} (${size} bytes)`);
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ ok: true }));
      });
    });
  } else {
    res.writeHead(404, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ error: 'not found' }));
  }
});

server.listen(PORT, '127.0.0.1', () => {
  console.log(`Log receiver listening on 127.0.0.1:${PORT}`);
});

मुख्य बिंदु:

  • केवल 127.0.0.1 पर बाइंड होता है - इंटरनेट पर एक्सपोज़ नहीं
  • X-API-Key हेडर से रिक्वेस्ट प्रमाणित करता है
  • हर लॉग बैच को टाइमस्टैंप्ड JSON फाइल के रूप में लिखता है
  • प्रति रिक्वेस्ट 10MB पेलोड सीमा

2b. systemd सर्विस

/etc/systemd/system/log-receiver.service बनाएं:

[Unit]
Description=Shopify request log receiver
After=network.target

[Service]
Type=simple
Environment=LOG_API_KEY=<your-generated-api-key>
ExecStart=/usr/bin/node /opt/log-receiver/receive-logs.js
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

सक्षम और शुरू करें:

systemctl daemon-reload
systemctl enable --now log-receiver

चरण 3: Cloudflare Tunnel सेट करें

टनल Cloudflare के एज से आपके सर्वर तक एक सुरक्षित कनेक्शन बनाता है - कोई खुले पोर्ट नहीं, कोई फायरवॉल नियम आवश्यक नहीं।

3a. cloudflared इंस्टॉल करें

# Debian/Ubuntu
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb \
  -o /tmp/cloudflared.deb
dpkg -i /tmp/cloudflared.deb

3b. प्रमाणित करें

cloudflared tunnel login
# Opens a browser (or gives you a URL) to authorize with your Cloudflare account

यह ~/.cloudflared/ में एक cert.pem सेव करता है।

3c. टनल बनाएं

cloudflared tunnel create shopify-log-collector

यह एक Tunnel ID (एक UUID) आउटपुट करता है और ~/.cloudflared/ में एक क्रेडेंशियल JSON फाइल बनाता है।

3d. टनल कॉन्फ़िगर करें

~/.cloudflared/config.yml बनाएं:

tunnel: <YOUR-TUNNEL-ID>
credentials-file: /root/.cloudflared/<YOUR-TUNNEL-ID>.json

ingress:
  - hostname: log-collector.yourdomain.com
    service: http://localhost:9090
  - service: http_status:404
  • hostname: वह सबडोमेन जिस पर आपका Worker लॉग POST करेगा
  • service: localhost:9090 पर आपके Node.js रिसीवर तक रूट करता है
  • कैच-ऑल नियम: किसी भी अन्य hostname के लिए 404 लौटाता है (cloudflared के लिए आवश्यक)

3e. DNS रिकॉर्ड बनाएं

cloudflared tunnel route dns shopify-log-collector log-collector.yourdomain.com

यह आपके Cloudflare DNS में एक CNAME रिकॉर्ड बनाता है:

log-collector.yourdomain.com  →  <TUNNEL-ID>.cfargotunnel.com

रिकॉर्ड Cloudflare के माध्यम से प्रॉक्सी किया जाता है (ऑरेंज क्लाउड) - CNAME में टनल ID सार्वजनिक रूप से अर्थहीन है।

3f. सिस्टम सर्विस के रूप में इंस्टॉल करें

cloudflared service install
systemctl enable --now cloudflared

यह आपके कॉन्फ़िग को /etc/cloudflared/config.yml में कॉपी करता है और एक systemd यूनिट बनाता है।

टनल सत्यापित करें

systemctl status cloudflared
# Should show: active (running)

curl https://log-collector.yourdomain.com/status
# Should return: {"status":"ok"}

चरण 4: अपनी API Key जनरेट करें

Worker और रिसीवर के बीच साझा एक रैंडम API key जनरेट करें:

openssl rand -hex 32

यह मान सेट करें:

  1. wrangler secret put INGEST_API_KEY के माध्यम से Worker secret के रूप में
  2. रिसीवर की systemd Environment लाइन में (LOG_API_KEY=…)

चरण 5: एंड-टू-एंड सत्यापित करें

  1. ब्राउज़र में अपने Shopify स्टोर पर जाएं
  2. रिसीवर लॉग जांचें:
journalctl -u log-receiver -f
# Should show: Wrote logs-1234567890-abc123.json (1234 bytes)
  1. लॉग फाइल का निरीक्षण करें:
cat /var/log/cdn-requests/logs-*.json | head -1 | python3 -m json.tool

आपको रिक्वेस्ट विवरण, भौगोलिक डेटा, और प्रदर्शन मेट्रिक्स के साथ एक पूर्ण लॉग एंट्री दिखनी चाहिए।

नमूना लॉग एंट्री

{
  "logs": [{
    "timestamp": "2026-03-04T15:19:55.584Z",
    "method": "GET",
    "url": "https://www.yourdomain.com/products/example",
    "path": "/products/example",
    "host": "www.yourdomain.com",
    "userAgent": "Mozilla/5.0 ...",
    "ip": "198.51.100.23",
    "country": "US",
    "city": "Seattle",
    "asn": 16509,
    "asOrganization": "Amazon.com",
    "colo": "SEA",
    "edgeTimeToFirstByteMs": 109,
    "originResponseStatus": 200,
    "cacheCacheStatus": "HIT",
    "botName": "other",
    "botType": "unknown"
  }]
}

पूर्ण Shopify लॉगिंग पाइपलाइन कैसे काम करती है?

कंपोनेंट यह क्या करता है कहां चलता है
Cloudflare Worker हर रिक्वेस्ट को इंटरसेप्ट करता है, Shopify को प्रॉक्सी करता है, लॉग एंट्री भेजता है Cloudflare एज (Wrangler के माध्यम से डिप्लॉय)
Cloudflare Tunnel Cloudflare एज को आपके सर्वर से सुरक्षित रूप से जोड़ता है (कोई खुले पोर्ट नहीं) आपके सर्वर पर cloudflared डेमन
DNS CNAME log-collector.yourdomain.com से <tunnel-id>.cfargotunnel.com आपके ज़ोन के लिए Cloudflare DNS
Node.js रिसीवर JSON लॉग POST स्वीकार करता है, API key से प्रमाणित करता है, डिस्क पर लिखता है आपका सर्वर, localhost:9090 पर बाउंड

डेटा प्रवाह

1. Visitor hits https://www.yourdomain.com/products/something
2. Cloudflare routes through the Worker
3. Worker fetches origin response from Shopify → returns it to visitor
4. Worker POSTs { logs: [entry] } to https://log-collector.yourdomain.com/collect
   (non-blocking - visitor doesn't wait for this)
5. Cloudflare resolves log-collector.yourdomain.com via tunnel CNAME
6. Tunnel forwards request to localhost:9090 on your server
7. Receiver validates X-API-Key, writes JSON file to disk

Shopify कौन सा रिक्वेस्ट डेटा कैप्चर कर सकता है जो Shopify आपको नहीं दिखाएगा?

Shopify का एडमिन आपको पेज व्यू, ऑर्डर, और रेफरल स्रोत दिखाता है। यह नहीं दिखाता कि कौन से AI बॉट आए, उन्होंने कौन से पेज फ़ेच किए, वे कहां से आए, या आपके सर्वर ने कितनी तेज़ी से प्रतिक्रिया दी। यह सेटअप इन श्रेणियों में प्रति रिक्वेस्ट 40+ फ़ील्ड कैप्चर करता है:

श्रेणी फ़ील्ड
रिक्वेस्ट timestamp, method, url, path, host, userAgent, ip, referer
बॉट पहचान botName, botType (realtime / crawler / preview / unknown)
Cloudflare भौगोलिक डेटा country, region, city, postalCode, latitude, longitude, timezone, continent
नेटवर्क asn, asOrganization, colo, httpProtocol, tlsVersion
Client Hints sec-ch-ua, sec-ch-ua-mobile, sec-ch-ua-platform
Fetch Metadata sec-fetch-dest, sec-fetch-mode, sec-fetch-site
प्रदर्शन edgeTimeToFirstByteMs, clientTcpRttMs, cacheCacheStatus, originResponseStatus

Client Hints और Fetch Metadata विशेष रूप से हेडलेस ब्राउज़र और अहस्ताक्षरित बॉट की पहचान के लिए उपयोगी हैं - वास्तविक ब्राउज़र ये हेडर भेजते हैं, अधिकांश बॉट नहीं भेजते।


कौन से AI बॉट आपके Shopify स्टोर पर आ रहे हैं?

Shopify मानव विज़िटर और AI क्रॉलर के बीच अंतर नहीं करता। यह Worker हर User-Agent को दो श्रेणियों में वर्गीकृत करता है जो AI विज़िबिलिटी के लिए महत्वपूर्ण हैं:

प्रकार विवरण उदाहरण
realtime उपयोगकर्ता प्रश्नों के जवाब में पेज फ़ेच करने वाले AI सहायक ChatGPT-User, Claude-Web, Perplexity-User
crawler सर्च या AI ट्रेनिंग के लिए सामग्री इंडेक्स करने वाले बॉट GPTBot, Googlebot, ClaudeBot, Bingbot

अज्ञात User-Agent से आने वाली रिक्वेस्ट को other / unknown टैग किया जाता है - आप बाद में अहस्ताक्षरित क्रॉलर खोजने के लिए इनका विश्लेषण कर सकते हैं। यह वह डेटा है जो Shopify, Google Analytics, और अधिकांश SaaS एनालिटिक्स प्लेटफॉर्म बस प्रदान नहीं करते।


गहन विश्लेषण के लिए Shopify बॉट डेटा को डेटाबेस में कैसे स्टोर करें

गहन बॉट एनालिटिक्स के लिए, आप डिस्क के अलावा Supabase (या किसी भी डेटाबेस) में बॉट रिक्वेस्ट लॉग करने के लिए Worker का विस्तार कर सकते हैं। ये Worker secrets जोड़ें:

wrangler secret put SUPABASE_URL
wrangler secret put SUPABASE_SERVICE_KEY

फिर एक logToDatabase() फ़ंक्शन जोड़ें जो आपके डेटाबेस के REST API पर POST करता है, ज्ञात बॉट रिक्वेस्ट के लिए ctx.waitUntil() के माध्यम से कॉल किया जाता है। यह आपको रॉ लॉग फाइलों के साथ-साथ संरचित, क्वेरी योग्य बॉट डेटा देता है।


रिक्वेस्ट लॉगिंग के साथ Shopify स्टोर के लिए Cloudflare DNS कैसे कॉन्फ़िगर करें

इस सेटअप के काम करने के लिए, आपका डोमेन Cloudflare के माध्यम से प्रॉक्सी किया जाना चाहिए (ऑरेंज क्लाउड)। एक सामान्य Shopify + Cloudflare DNS सेटअप:

प्रकार नाम लक्ष्य प्रॉक्सी
CNAME www shops.myshopify.com प्रॉक्सीड (ऑरेंज)
CNAME log-collector <tunnel-id>.cfargotunnel.com प्रॉक्सीड (ऑरेंज)

www CNAME Shopify की ओर इशारा करता है - Cloudflare प्रॉक्सी और कैश करता है। log-collector CNAME आपकी टनल की ओर इशारा करता है - Cloudflare लॉग ट्रैफिक को सुरक्षित रूप से आपके सर्वर तक रूट करता है।

महत्वपूर्ण: Worker रूट प्रॉक्सीड hostname से मेल खाना चाहिए (जैसे, www.yourdomain.com/*)। यह नॉन-प्रॉक्सीड (ग्रे क्लाउड) रिकॉर्ड पर ट्रिगर नहीं होगा।


अपनी Shopify लॉग पाइपलाइन की निगरानी और रखरखाव कैसे करें

# Check receiver status
systemctl status log-receiver

# Check tunnel status
systemctl status cloudflared

# Tail live logs
journalctl -u log-receiver -f

# Count stored log files
ls /var/log/cdn-requests/*.json | wc -l

# Check disk usage
du -sh /var/log/cdn-requests/

डिस्क उपयोग की निगरानी और स्टोरेज सीमा के करीब पहुंचने पर अलर्ट करने के लिए एक cron जॉब जोड़ने पर विचार करें।


अक्सर पूछे जाने वाले प्रश्न

Shopify स्टोर मालिक सर्वर लॉग तक क्यों नहीं पहुंच सकते?

Shopify एक पूर्ण प्रबंधित SaaS प्लेटफॉर्म है। स्टोर मालिकों को अंतर्निहित सर्वर बुनियादी ढांचे तक पहुंच नहीं है, जिसका अर्थ है रॉ HTTP रिक्वेस्ट लॉग, एक्सेस लॉग, या एरर लॉग तक कोई पहुंच नहीं। Shopify अपना खुद का एनालिटिक्स डैशबोर्ड प्रदान करता है जिसमें पेज व्यू, ऑर्डर, और रेफरल डेटा शामिल है, लेकिन इसमें व्यक्तिगत HTTP रिक्वेस्ट, बॉट User-Agent, रिस्पॉन्स टाइम, या रिक्वेस्ट स्तर पर भौगोलिक डेटा शामिल नहीं है। Shopify Plus सहित कोई भी Shopify प्लान रॉ सर्वर लॉग एक्सेस प्रदान नहीं करता। इस डेटा को कैप्चर करने का एकमात्र तरीका Shopify के ओरिजिन सर्वर तक पहुंचने से पहले CDN लेयर पर रिक्वेस्ट को इंटरसेप्ट करना है।

Shopify स्टोर पर AI बॉट ट्रैफिक कैसे ट्रैक करें?

AI बॉट ट्रैफिक को Google Analytics, Shopify Analytics, या किसी भी क्लाइंट-साइड JavaScript एनालिटिक्स टूल के माध्यम से ट्रैक नहीं किया जा सकता क्योंकि AI बॉट JavaScript एक्सीक्यूट नहीं करते। एकमात्र विश्वसनीय तरीका सर्वर-साइड रिक्वेस्ट लॉगिंग है। Shopify स्टोर के लिए, इसका मतलब है Cloudflare Worker (या किसी अन्य CDN पर समकक्ष एज फ़ंक्शन) का उपयोग करके CDN लेयर पर रिक्वेस्ट को इंटरसेप्ट करना। Worker हर आने वाली रिक्वेस्ट को लॉग करता है, जिसमें User-Agent हेडर शामिल है, जो ChatGPT-User, GPTBot, ClaudeBot, PerplexityBot और अन्य जैसे विशिष्ट AI बॉट की पहचान करता है। यह वही दृष्टिकोण है जो उभरते “एजेंट एनालिटिक्स” प्लेटफॉर्म द्वारा उपयोग किया जाता है, लेकिन सेल्फ-होस्टेड और पूरी तरह से आपके नियंत्रण में।

अभी कौन से AI बॉट Shopify स्टोर क्रॉल कर रहे हैं?

2026 तक, Shopify स्टोर पर आने वाले प्रमुख AI बॉट दो श्रेणियों में आते हैं। रियल-टाइम फ़ेच बॉट (ChatGPT-User, Claude-User, Perplexity-User) लाइव उपयोगकर्ता वार्तालापों के दौरान मांग पर सामग्री प्राप्त करते हैं। ट्रेनिंग क्रॉलर (GPTBot, ClaudeBot, PerplexityBot, Bytespider, Amazonbot, Applebot) मॉडल ट्रेनिंग और इंडेक्स निर्माण के लिए शेड्यूल पर सामग्री एकत्र करते हैं। सर्वर-साइड लॉगिंग के बिना, इनमें से कोई भी Shopify के एनालिटिक्स या Google Analytics में दिखाई नहीं देता।

Cloudflare प्रति रिक्वेस्ट कितने डेटा फ़ील्ड लॉग करता है?

यह सेटअप प्रति रिक्वेस्ट 40+ फ़ील्ड कैप्चर करता है, जिसमें शामिल हैं रिक्वेस्ट बेसिक्स (timestamp, method, URL, path, user agent, IP, referer), बॉट वर्गीकरण (बॉट नाम और प्रकार), Cloudflare भौगोलिक डेटा (country, region, city, postal code, latitude, longitude, timezone, continent), नेटवर्क जानकारी (ASN, organization, data center, HTTP protocol, TLS version), Client Hints (sec-ch-ua हेडर जो हेडलेस ब्राउज़र का पता लगाने में मदद करते हैं), Fetch Metadata (sec-fetch हेडर जो प्रोग्रामैटिक रिक्वेस्ट की पहचान करते हैं), और प्रदर्शन मेट्रिक्स (time to first byte, TCP round trip time, cache status, origin response status)।

Shopify के बिल्ट-इन एनालिटिक्स की तुलना में यह कैसा है?

Shopify का एनालिटिक्स डैशबोर्ड पेज व्यू, सेशन, कन्वर्शन रेट, और रेफरल स्रोत दिखाता है। यह व्यक्तिगत HTTP रिक्वेस्ट, बॉट User-Agent, रिक्वेस्ट स्तर पर भौगोलिक डेटा, रिस्पॉन्स प्रदर्शन मेट्रिक्स, या कोई भी AI बॉट गतिविधि नहीं दिखाता। Google Analytics, जिसके साथ Shopify इंटीग्रेट करता है, की भी वही सीमा है क्योंकि यह क्लाइंट-साइड JavaScript पर निर्भर करता है। यह Cloudflare-आधारित लॉगिंग सेटअप आपके डोमेन को छूने वाली हर रिक्वेस्ट को कैप्चर करता है, जिसमें उन बॉट से आने वाली रिक्वेस्ट भी शामिल हैं जो कभी JavaScript एक्सीक्यूट नहीं करते, जो आपको एक पूर्ण तस्वीर देता है जो Shopify के टूल प्रदान नहीं कर सकते।

क्या आप Cloudflare के अलावा किसी अन्य CDN के साथ इस सेटअप का उपयोग कर सकते हैं?

यह आर्किटेक्चर किसी भी एज CDN पर लागू होता है जो एज फ़ंक्शन और सुरक्षित टनलिंग का समर्थन करता है। Cloudflare Workers के अन्य प्लेटफॉर्म पर समकक्ष हैं: Vercel Edge Functions, AWS CloudFront Functions, Fastly Compute, और Akamai EdgeWorkers सभी रिक्वेस्ट इंटरसेप्ट कर सकते हैं और लॉग डेटा भेज सकते हैं। टनल कंपोनेंट को किसी भी सुरक्षित कनेक्शन विधि (SSH tunnel, VPN, IP allowlisting के साथ सीधा HTTPS एंडपॉइंट) से बदला जा सकता है। मूल पैटर्न वही है: एज पर इंटरसेप्ट करें, असिंक्रोनस रूप से लॉग करें, अपने रिसीवर को भेजें।