'ElasticsearchTransport use transform to change indexPrefix?

UPDATE: I can actually change the indexPrefix using the below code, but the actual _index which is used to filter in Kibana gets its name from the original indexPrefix. It seems changing the indexPrefix in the transformer method is too late, because the _index has already been created with the original prefix.

I'm using winston and winston-elasticsearch in a nodejs/express setup and want to use the same logger to log to different indexes (different indexPrefix)

const logger = winston.createLogger({
  transports
});

The transports is an array of different transports. One of them is an ElasticsearchTransport that takes in some parameters like indexPrefix and level among others. The level can be changed based on the type of log by passing in a transformer method as parameter.

    new winstonElastic.ElasticsearchTransport({
      level: logLevel,
      indexPrefix: getIndex(),
      messageType: 'log',
      ensureMappingTemplate: true,
      mappingTemplate: indexTemplateMapping,
      transformer: (logData: any) => {
        const transformed: any = {};
        transformed['@timestamp'] = logData.timestamp ? logData.timestamp : new Date().toISOString();
        transformed.message = logData.message;
        transformed.level = parseWinstonLevel(logData.level);
        transformed.fields = _.extend({}, staticMeta, logData.meta);
        transformed.indexPrefix = getIndex(logData.indexPrefix);
        return transformed;
      },

The transformer method is called whenever the logger writes a new entry and i can verify that it works by setting properties like message. It also overwrites the level to whatever the current log level is. For some reason it doesn't work on the property indexPrefix - even when it changes, nothing overwrites the initial indexPrefix. I even tried to remove the initial value but then the logging fails, having never set the indexPrefix.

Does anyone know why? Does it have to do with the mappingTemplate listed below?:

{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0,
    "index": {
      "refresh_interval": "5s"
    }
  },
  "mappings": {
    "properties": {
      "@timestamp": { "type": "date" },
      "@version": { "type": "keyword" },
      "message": { "type": "text" },
      "severity": { "type": "keyword" },
      "fields": {
        "dynamic": true,
        "properties": {}
      }
    }
  }
}


Solution 1:[1]

Ok, if anyone is interrested. I ended up making a loggerFactory instead. I create a logger seeded with the correct indexPrefix through the factory - that way I end up with one logger instance per indexPrefix i want...

Solution 2:[2]

For those who are having the same problem i solved this in a different way.

1 - I created a variable inside ElasticsearchTransport scope; 2 - I changed the value of the variable inside the transformer method; 3 - I used the variable inside the indexPrefix method to define which prefix to use:

indexPrefix: () => return variable ? 'test1' : 'test2'

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Per Hornshøj-Schierbeck
Solution 2 Farah