telemetry.ts file in Flyde codebase.

Ramu NarasingaRamu Narasinga
3 min read

In this article, we will review telemetry.ts file in Flyde codebase. We will look at:

  1. reportEvent().

  2. sanitizeProperties().

  3. isSafeProperty().

  4. sanitizeValue().

reportEvent()

reportEvent function is exported in telemetry.ts file as shown below:

export function reportEvent(
  distinctId: string,
  event: string,
  properties?: Record<string, any>
): void {
  // Check if telemetry is disabled via environment variable
  if (typeof process !== 'undefined' && process.env?.FLYDE_TELEMETRY_DISABLED === 'true') {
    return;
  }

  // Disable in CI/CD and production environments
  if (typeof process !== 'undefined' && process.env) {
    const env = process.env;

    // Disable in CI
    if (env.CI === 'true') {
      return;
    }

    // Disable in production
    if (env.NODE_ENV === 'production') {
      return;
    }
  }

  // Fire and forget
  (async () => {
    try {
      const sanitizedProperties = sanitizeProperties(properties);
      const payload: TelemetryEvent = {
        distinctId,
        event,
        properties: {
          ...sanitizedProperties,
          flydeVersion: FLYDE_VERSION
        }
      };

      fetch(TELEMETRY_ENDPOINT, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(payload)
      });
    } catch (error) {
      // Silently fail - telemetry should not break the app
    }
  })();
}

This code snippet is self explanatory with helpful comments. What I find interesting is that “fire and forget” type of invocation. This is an IIFE.

Also notice that catch block is empty.

sanitizeProperties()

sanitizeProperties is defined as shown below:

function sanitizeProperties(properties?: Record<string, any>): Record<string, any> {
  if (!properties) {
    return {};
  }

  const sanitized: Record<string, any> = {};

  for (const [key, value] of Object.entries(properties)) {
    if (isSafeProperty(key, value)) {
      sanitized[key] = sanitizeValue(value);
    }
  }

  return sanitized;
}

This function iterates over the object keys and checks if it is a safe property and then sanitizes value.

Two questions come to mind.

  1. What does safe here mean?

  2. What does sanitize value here mean?

Continue reading.

isSafeProperty()

isSafeProperty function is defined as shown below:

function isSafeProperty(key: string, _value: any): boolean {
  const sensitiveKeys = [
    'token', 'password', 'secret', 'key', 'auth', 'credential',
    'email', 'username', 'path', 'file', 'content', 'code'
  ];

  const lowerKey = key.toLowerCase();
  if (sensitiveKeys.some(sensitive => lowerKey.includes(sensitive))) {
    return false;
  }

  return true;
}

Interesting usage of “some” here and this is based on sensitiveKeys array.

sanitizeValue()

sanitizeValue is defined as shown below:

function sanitizeValue(value: any): any {
  if (typeof value === 'string' && value.length > 100) {
    return '[Redacted]';
  }

  if (typeof value === 'object' && value !== null) {
    return '[Object]';
  }

  return value;
}

sanitize here means sensitive info gets redacted and if the value is of type object, it returns [Object].

About me:

Hey, my name is Ramu Narasinga. I study codebase architecture in large open-source projects.

Email: ramu.narasinga@gmail.com

Want to learn from open-source? Solve challenges inspired by open-source projects.

References:

  1. https://github.com/flydelabs/flyde/blob/main/core/src/telemetry.ts

  2. https://github.com/search?q=repo%3Aflydelabs%2Fflyde+FLYDE_VERSION&type=code

  3. https://github.com/search?q=repo%3Aflydelabs%2Fflyde+telemetry&type=code

0
Subscribe to my newsletter

Read articles from Ramu Narasinga directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ramu Narasinga
Ramu Narasinga

I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.