Создание журналов для веб-приложения на Javascript

#javascript #logging #web-applications #client

#javascript #ведение журнала #веб-приложения #клиент

Вопрос:

У меня есть вариант использования, в котором я хотел бы генерировать журналы для моего веб-приложения JS, которые могли бы храниться в виде файла на стороне клиента (храниться на компьютере пользователя).

Поэтому я хочу знать, какому подходу я могу следовать для создания журналов в JS?

Комментарии:

1. В чем? Браузер? Браузерный код JavaScript не может записывать в произвольные файлы на компьютере пользователя. Это было бы серьезной проблемой безопасности.

2. «Я видел библиотеки для Node JS, но не могу найти ни одной для vanilla JS». Node.js это не вариант JavaScript. Это среда хоста. То же самое относится и к веб-браузеру. Оба выполняют «ванильный» JavaScript в разных средах.

Ответ №1:

Если вы имеете в виду, что хотите сделать это из кода JavaScript, размещенного в браузере, боюсь, вы не сможете. Браузерный код JavaScript не может записывать в произвольные файлы на компьютере пользователя. Это было бы серьезной проблемой безопасности.

Вы можете хранить «журнал» в веб-хранилище, но обратите внимание, что веб-хранилище имеет ограничения по размеру, поэтому вы не хотите, чтобы оно становилось слишком большим.

Вот простая функция ведения журнала, которая добавляется к журналу в локальном хранилище:

 function log(...msgs) {
    // Get the current log's text, or "" if there isn't any yet
    let text = localStorage.getItem("log") || "";
    // Add this "line" of log data
    text  = msgs.join(" ")   "rn";
    // Write it back to local storage
    localStorage.setItem("log", text);
}
 

Очевидно, что затем вы можете использовать это различными способами (уровни журнала, регистрация даты / времени и т. Д.).

Комментарии:

1. является ли IndexDB хорошим местом? я имею в виду его асинхронность и не блокирует поток, такой как localstorage

2. @Ifaruki — У меня есть плохая привычка забывать об IndexedDB. Это не будет работать для всех тех людей, которые все еще (!) используют IE, но теперь, когда Edge основан на Chromium, поддержка хорошая . Итак, я бы сказал: да, безусловно! Если вы можете привести пример, пожалуйста, не стесняйтесь редактировать его в приведенном выше (это сообщение вики сообщества) или опубликовать свой собственный ответ. Если вы сделаете последнее, пожалуйста, свяжитесь со мной (ТАК же, как и с первым) — я очень хочу это увидеть. 🙂

Ответ №2:

Вы можете использовать локальное хранилище для имитации файла :

Создайте идентификатор для каждой строки вашего «файла» и сохраните номер последней строки

 function logIntoStorage (pMsg) {
    if (!pMsg) pMsg = "pMsg is not here !";
    if ((typeof pMsg) != "string") pMsg = "pMsg is Not a string:" (typeof pMsg);        
    let logNb = "logNb";
    let padLong = 7;
    let strLg = "0";
    let lg = 0;
    let maxSize = 50; // max nb of lines in the log
    
    // Reading log num line
    strLg = localStorage.getItem(logNb);
    if(!strLg) { //logNb not stored yet
        lg = 0;
        strLg = "0";
        localStorage.setItem(logNb, lg.toString(10)); // store the number of cur line
    } else { // Read logNb from storage
        strLg = localStorage.getItem(logNb);
        lg = parseInt(strLg,10);
    } 
        
    if (lg >= maxSize) {
       lg = maxSize; // size limit nb lines.
       pMsg = "LIMIT SIZE REACHED";
    }


    // log msg into localStorage at logLine:0000#### 
    let s = ("0000000000000000" strLg).substr(-padLong);  // padding zeros
    localStorage.setItem("logLine:" s, pMsg);
    
    if (lg >= maxSize) return;
    lg  ;  // point to the next line
    localStorage.setItem(logNb, lg.toString(10));
}
 

Ответ №3:

В современном Chrome вы можете фактически «передавать» данные на диск пользователя после того, как они дадут разрешение, благодаря API доступа к файловой системе.

Для этого вам нужно запросить файл для сохранения, позвонив showSaveFilePicker() .

Как только вы получите одобрение пользователя, вы получите дескриптор, из которого вы сможете получить записываемый поток.
Как только вы закончите писать, вам просто нужно к .close() писателю.

 onclick = async () => {

  if( !("showSaveFilePicker" in self) ) {
    throw new Error( "unsupported browser" );
  }

  const handle = await showSaveFilePicker();
  const filestream = await handle.createWritable();
  const writer = await filestream.getWriter();
  // here we have a WritableStream, with direct access to the user's disk
  // we can write to it as we wish
  writer.write( "hello" );
  writer.write( " world" );
  // when we're done writing
  await writer.ready;
  writer.close();

};

 

Живой пример.

Комментарии:

1. Это действительно интересное решение. Я считаю, что не будет никаких ограничений на размер хранилища, кроме размера диска. Я хотел знать, есть ли какие-либо другие недостатки, о которых вы могли бы знать, например, Производительность и т. Д.?

2. Самым большим недостатком является поддержка браузера, на сегодняшний день только Chrome. С точки зрения производительности, это так быстро, как только может работать ваш жесткий диск. Что касается ограничения объема памяти, действительно, это должен быть размер диска, хотя могут быть ограничения, о которых я не знаю.