1.0.29 • Published 5 years ago

my-log-data v1.0.29

Weekly downloads
-
License
MIT
Repository
-
Last release
5 years ago

Installation

cp src/config.example.js src/config.js

Hello

  1. There are currently only 1 endpoint for logging.
  2. No general endpoint for analysis or aggregation exists, because they are hard to do (I tried). So, specific questions need specific endpoints.
  3. Data is logged to MongoDB, but perhaps it should be on FileSystem (Append to AWS file?) and if structure for data changes.

Create a log

Mutation to call

mutation {
  myLogCreate(
    service: "service-name"
    uniqueDeviceId: "unique-device-id"
    clientIp: "client-ip"
    data: "{\"important\":\"information\"}"
  ) {
    log {
      id
      service
      uniqueDeviceId
      clientIp
      data
      createdAt
    }
    tookTime
  }
}

Client implementation and referals example

JavaScript implementation for including in

THIS IS RECOMMENDED APPROACH AND OTHER APPROACHES ARE OUTDATED.

<script type="application/javascript">
  (function() {
    // window.MY_LOG_DATA_GRAPHQL_ENDPOINT="https://same.as.opened.domain/graphql"; as default
  })();
</script>
<script src="https://cdn.coingaming.io/client-helpers/client-helpers.js" />

Please see ./examples/client-helpers.js as an example.

With Server Side Rendering (ExpressJS)

// server/util/tracking/ensureUniqueDeviceId.ts
import randomString from '~/client/utils/string/randomString';

const ensureUniqueDeviceId = ({ req, res }) => {
  const existingUniqueDeviceId = req.cookies.uniqueDeviceId;
  if (existingUniqueDeviceId) {
    return existingUniqueDeviceId;
  }

  const newUniqueDeviceId = `${Date.now()}-${randomString(10)}`;
  // tslint:disable-next-line: no-object-mutation
  req.cookies.uniqueDeviceId = newUniqueDeviceId;
  res.cookie('uniqueDeviceId', newUniqueDeviceId, {
    expires: new Date(Date.now() * 10),
  });
  return newUniqueDeviceId;
};

export default ensureUniqueDeviceId;
// server/util/tracking/logPageOpen.ts
import myLogCreate from './myLogCreate';
import { getRequestIp } from '~/server/getCountryByIp';

const logPageOpen = async ({ req, statusCode, uniqueDeviceId }) => {
  const referer = req.get('Referer');
  const entryHost = req.get('Host');
  const clientIp = getRequestIp(req);

  const notSelfReferer =
    referer &&
    !referer.startsWith(`http://${entryHost}`) &&
    !referer.startsWith(`https://${entryHost}`);

  if (referer && notSelfReferer) {
    await myLogCreate({
      uniqueDeviceId,
      clientIp,
      service: 'open-by-referer',
      data: JSON.stringify({
        statusCode,
        referer,
        entryHost,
        entryPath: req.path,
      }),
    });
    return true;
  }
};

export default logPageOpen;
// server/util/tracking/logPageOpen.ts
import myLogCreate from './myLogCreate';
import { getRequestIp } from '~/server/getCountryByIp';

const logPageOpen = async ({ req, statusCode, uniqueDeviceId }) => {
  const referer = req.get('Referer');
  const entryHost = req.get('Host');
  const clientIp = getRequestIp(req);

  const notSelfReferer =
    referer &&
    !referer.startsWith(`http://${entryHost}`) &&
    !referer.startsWith(`https://${entryHost}`);

  if (referer && notSelfReferer) {
    await myLogCreate({
      uniqueDeviceId,
      clientIp,
      service: 'open-by-referer',
      data: JSON.stringify({
        statusCode,
        referer,
        entryHost,
        entryPath: req.path,
      }),
    });
    return true;
  }
};

export default logPageOpen;
// server/util/tracking/myLogCreate.ts
const mutation = `
  mutation(
    $service: String
    $uniqueDeviceId: String
    $clientIp: String
    $data: String
  ) {
    myLogCreate(
      service: $service
      uniqueDeviceId: $uniqueDeviceId
      clientIp: $clientIp
      data: $data
    ) {
      log {
        id
      }
    }
  }
`;

const { log } = console;

const myLogCreate = async ({ service, uniqueDeviceId, clientIp, data }) => {
  const variables = { service, uniqueDeviceId, clientIp, data };
  const headers = { 'Content-Type': 'application/json' };
  const body = JSON.stringify({ variables, query: mutation });
  const method = 'POST';

  try {
    const mutationHttpResult = await fetch(process.env.GRAPHQL_SERVER_URL, {
      method,
      headers,
      body,
    });
    return await mutationHttpResult.json();
  } catch (e) {
    log(`Unable to call myLogCreate with ${body} ${e}`);
  }
};

export default myLogCreate;
// express endpoint
export const serverSideRendering = async (req: Request, res: Response) => {
  const context: any = {};
  sendNoCacheHeaders(res);
  const uniqueDeviceId = ensureUniqueDeviceId({ req, res });

  try {
    if (context.url) {
      return res.redirect(context.url);
    }
    const ssrStartTime = process.hrtime();
    const html = await getRenderedApp(req, res, context);
    const statusCode = context.statusCode || 200;
    logTiming(res, 'SSRTotalTime', ssrStartTime);
    logPageOpen({ req, statusCode, uniqueDeviceId });

    res
      .status(statusCode)
      .send(html || 'Please try again')
      .end();
  } catch (error) {
    console.error({ error });
    const maintenancePage = await getMaintenancePage(req);
    const statusCode = context.statusCode || 500;
    logPageOpen({ req, statusCode, uniqueDeviceId });
    res
      .status(statusCode)
      .send(maintenancePage)
      .end();
  }
};

Typescript implementation for Single Page App (React, Preact etc)

import { getItem, setItem } from '../../engines/cookieStorage';
import randomString from '~/client/utils/string/randomString';

const KEY = 'uniqueDeviceId';

const getUniqueDeviceId = () => {
  const clientUniqueIdInCookie = getItem(KEY);
  if (clientUniqueIdInCookie) {
    return clientUniqueIdInCookie;
  }

  const clientUniqueId = `${Date.now()}-${randomString(10)}`;
  setItem(KEY, clientUniqueId);
  return clientUniqueId;
};

export default getUniqueDeviceId;
// src/client/apolloClient.ts
import getUniqueDeviceId from './shared/storage/persistence/uniqueDeviceId/getUniqueDeviceId';

// ...

const withHeadersLink = setContext((_, { headers }) => {
  const token = getToken();
  const uniqueDeviceId = getUniqueDeviceId();
  return {
    headers: {
      ...headers,
      'x-unique-device-id': uniqueDeviceId,
      authorization: token ? `Bearer ${token}` : '',
    },
  };
});

const wsLink = new WebSocketLink(subscriptionClient);

const link = split(
  // ...
  wsLink,
  afterwareLink.concat(withHeadersLink.concat(httpLink)),
);

export const apolloClient = new ApolloClient({
  link,
  // ...
});

Running locally (without Docker)

cp src/config.example.js src/config.js
node src/index.js

Running locally (with Docker)

docker build -t heathmont/my-log-data:latest .
docker run --rm -it  -p 51234:80 -e MONGO_URL="mongodb://test4/log-data" -e SERVICE_PORT="5611" heathmont/my-log-data:latest

Deploy from stacks

export DOCKER_HOST=test4.casino.testenv.io
deploy-stack bitcasino
1.0.19

5 years ago

1.0.18

5 years ago

1.0.17

5 years ago

1.0.16

5 years ago

1.0.9

5 years ago

1.0.8

5 years ago

1.0.7

5 years ago

1.0.6

5 years ago

1.0.5

5 years ago

1.0.4

5 years ago

1.0.3

5 years ago

1.0.22

5 years ago

1.0.21

5 years ago

1.0.20

5 years ago

1.0.26

5 years ago

1.0.25

5 years ago

1.0.24

5 years ago

1.0.23

5 years ago

1.0.29

5 years ago

1.0.28

5 years ago

1.0.27

5 years ago

1.0.11

5 years ago

1.0.10

5 years ago

1.0.15

5 years ago

1.0.14

5 years ago

1.0.13

5 years ago

1.0.12

5 years ago