Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Логирование данных в файл на С. / 25 сообщений из 26, страница 1 из 2
20.03.2018, 12:30
    #39617409
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
У меня по всему коду разбросанны сообщения типа
printf ("LIB ID = %d\n", lib_id);
сообщения выводятся серийно на терминал.
Сейчас нужно некоторые сообщения логировать в файл на SD карте.
Возникли вопросы по алгоритмике логирования данных
1. Прежде всего проверить есть ли место на SD - вопрос как это сделать? и если нет места? очистить файл и начать писать сначала?
2. Если файл открыт - добавить данные в файл, посмотреть флаг закрыть файл или нет.(я не хочу часто дергать файл - открывать\закрывать)
тогда что - держать глобальный указатель на файл?
3.Если файл закрыт - открыть с опцией "а+", добавить данные в файл, посмотреть флаг закрыть файл или нет.
Как вообще сделать покрасивше?
...
Рейтинг: 0 / 0
20.03.2018, 12:34
    #39617413
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
jenya7если нет места? очистить файл и начать писать сначала?Сообщить о недостатке места и завершить работу или запросить новое местоположение лога. Нельзя уничтожать чужие данные.
...
Рейтинг: 0 / 0
20.03.2018, 12:54
    #39617443
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
jenya7У меня по всему коду разбросанны сообщения типа
printf ("LIB ID = %d\n", lib_id);
сообщения выводятся серийно на терминал.
Сейчас нужно некоторые сообщения логировать в файл на SD карте.
Возникли вопросы по алгоритмике логирования данных
1. Прежде всего проверить есть ли место на SD - вопрос как это сделать? и если нет места? очистить файл и начать писать сначала?
Рекомендую периодически начинать новый файл, а старый переименовывать. Например при достижении какого-то размера.
Что делать со старыми тебе видней, если старая инфа неинтересна, то можно удалять через какое-то время.
jenya72. Если файл открыт - добавить данные в файл, посмотреть флаг закрыть файл или нет.(я не хочу часто дергать файл - открывать\закрывать)
тогда что - держать глобальный указатель на файл?
ИМХО лучше функцию отдельную сделать и там всю логику прописать
Код: sql
1.
2.
3.
4.
void write_log(const char* data, ...) {
  static FILE* f = NULL;
  if(f == NULL) {
     f = fopen(...

jenya73.Если файл закрыт - открыть с опцией "а+", добавить данные в файл, посмотреть флаг закрыть файл или нет.
Как вообще сделать покрасивше?
Если файл не закрываешь, то обязательно fflush() после записи, т.к. иначе при вылете проги часть лога может остаться в буфере ОС и не запишется на диск.
...
Рейтинг: 0 / 0
20.03.2018, 13:37
    #39617495
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
Dima Tjenya7У меня по всему коду разбросанны сообщения типа
printf ("LIB ID = %d\n", lib_id);
сообщения выводятся серийно на терминал.
Сейчас нужно некоторые сообщения логировать в файл на SD карте.
Возникли вопросы по алгоритмике логирования данных
1. Прежде всего проверить есть ли место на SD - вопрос как это сделать? и если нет места? очистить файл и начать писать сначала?
Рекомендую периодически начинать новый файл, а старый переименовывать. Например при достижении какого-то размера.
Что делать со старыми тебе видней, если старая инфа неинтересна, то можно удалять через какое-то время.
jenya72. Если файл открыт - добавить данные в файл, посмотреть флаг закрыть файл или нет.(я не хочу часто дергать файл - открывать\закрывать)
тогда что - держать глобальный указатель на файл?
ИМХО лучше функцию отдельную сделать и там всю логику прописать
Код: sql
1.
2.
3.
4.
void write_log(const char* data, ...) {
  static FILE* f = NULL;
  if(f == NULL) {
     f = fopen(...

jenya73.Если файл закрыт - открыть с опцией "а+", добавить данные в файл, посмотреть флаг закрыть файл или нет.
Как вообще сделать покрасивше?
Если файл не закрываешь, то обязательно fflush() после записи, т.к. иначе при вылете проги часть лога может остаться в буфере ОС и не запишется на диск.
Что то вроде этого?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
FILE *g_log_fp;
int g_log_file_size;

void LOG_LogMessage(char *file, char *message, int value, int close)
{
	int file_size = 0;
	
	char buff[256] = { '\0' };
	char sval[10];
	
	ItoA(value, sval);
	strcat(buff, message);
	strcat(buff, sval);

	if (g_log_fp == NULL)
	{
		g_log_fp = fopen(file, "a+");
		
		if (g_log_fp != NULL)
			fputs(buff, g_log_fp);
	}
	else
		fputs(buff, g_log_fp);
	
	fseek(g_log_fp, 0, SEEK_SET);
	fseek(g_log_fp, 0, SEEK_END);
	file_size = ftell(g_log_fp); 
			
	if (close)
		fclose(g_log_fp);
	else
		fflush(g_log_fp); 
	
	if (file_size >= MAX_LOG_FILE_SIZE)
	{
		//LOG_Clear() ???
		//go to the next file ???
	}	
}
...
Рейтинг: 0 / 0
20.03.2018, 13:46
    #39617499
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
Делай переменное количество параметров, как у printf(). Пример тут http://www.cplusplus.com/reference/cstdio/vsprintf/?kw=vsprintf

И не надо fseek(). Ты же знаешь размер добавляемого. При открытии посчитай текущий размер, а дальше к нему добавляй размер записанного и 1-2 байта на перевод строки.

Передавать имя файла в параметрах тоже не очень хорошая идея. Сделай глобальную переменную.
...
Рейтинг: 0 / 0
20.03.2018, 13:51
    #39617507
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
Не особо свежее, но готовое - zlog .
...
Рейтинг: 0 / 0
20.03.2018, 14:01
    #39617524
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
Basil A. SidorovНе особо свежее, но готовое - zlog .
фига се! там же монстр! :)
...
Рейтинг: 0 / 0
20.03.2018, 14:26
    #39617558
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
Dima TДелай переменное количество параметров, как у printf(). Пример тут http://www.cplusplus.com/reference/cstdio/vsprintf/?kw=vsprintf

И не надо fseek(). Ты же знаешь размер добавляемого. При открытии посчитай текущий размер, а дальше к нему добавляй размер записанного и 1-2 байта на перевод строки.

Передавать имя файла в параметрах тоже не очень хорошая идея. Сделай глобальную переменную.
Пока что получилось такое
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
FILE *g_log_fp;
int g_log_file_size;
char *glob_file_name;

void LOG_LogMessage(char *message, int value, int close)
{
	int file_size = 0;
	
	char buff[256] = { '\0' };
	char sval[10];
	
	ItoA(value, sval);
	strcat(buff, message);
	strcat(buff, sval);

	if (g_log_fp == NULL)
	{
		g_log_fp = fopen(glob_file_name, "a+");
		
		if (g_log_fp != NULL)
			fputs(buff, g_log_fp);
	}
	else
		fputs(buff, g_log_fp);
	
	//fseek(g_log_fp, 0, SEEK_SET);
	fseek(g_log_fp, 0, SEEK_END);
	file_size = ftell(g_log_fp); 
	g_log_file_size += file_size;
			
	if (close)
		fclose(g_log_fp);
	else
		fflush(g_log_fp); 
	
	if (g_log_file_size >= MAX_LOG_FILE_SIZE)
	{
		//LOG_Clear() ???
		//go to the next file ???
	}	
}

void LOG_LogString(char *message, int close)
{
	if (g_log_fp == NULL)
	{
		g_log_fp = fopen(glob_file_name, "a+");
			
		if (g_log_fp != NULL)
		    fputs(message, g_log_fp);
	}
	else
	    fputs(message, g_log_fp);
}

void LOG(char *message, int *value, int close, int log_option)
{
	switch (log_option)
	{
	    case LOG_ON_TERMINAL:
	    	if (value != NULL)
	    		printf(message, *value);
	    	else
	    		printf(message);
	    break;
	    case LOG_ON_FILE:
	    	if (value != NULL)
	    		LOG_LogMessage(message, *value,  close);
	    	else
	    		LOG_LogString(message, close);
	    break;
	    case LOG_ON_ALL:
	    	if (value != NULL)
	    	{
	    		printf(message, *value);
	    		LOG_LogMessage(message, *value,  close);
	    	}
	    	else
	    	{
	    		printf(message);
	    		LOG_LogString(message, close);
	    	}
	    break;
	}
...
Рейтинг: 0 / 0
20.03.2018, 14:42
    #39617574
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
Dima TДелай переменное количество параметров, как у printf(). Пример тут http://www.cplusplus.com/reference/cstdio/vsprintf/?kw=vsprintf.
Придется делать парсинг формата как в printf() а это уже через чур.
...
Рейтинг: 0 / 0
20.03.2018, 14:49
    #39617578
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
Лучше проверку в начало
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
void LOG_LogMessage(char *message, int value, int close)
{
	if (g_log_file_size >= MAX_LOG_FILE_SIZE)
	{
		//LOG_Clear() ???
		//go to the next file ???
// Закрыть файл и переименовать например в glob_file_name + ".YYYYMMDD_N"
fclose(g_log_fp);
g_log_fp = NULL;
	}	
...



ИМХО close не надо постоянно передавать, лучше сделай отдельно LOG_Close()
...
Рейтинг: 0 / 0
20.03.2018, 14:51
    #39617580
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
jenya7Dima TДелай переменное количество параметров, как у printf(). Пример тут http://www.cplusplus.com/reference/cstdio/vsprintf/?kw=vsprintf.
Придется делать парсинг формата как в printf() а это уже через чур.
Что в этом сложного? По ссылке пример как это делается.
...
Рейтинг: 0 / 0
20.03.2018, 14:58
    #39617584
d7i
d7i
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
Не забывайте при каждой записи в лог-файл сперва писать в начале строки текущую дату и время.
Весьма полезно. Я всегда так делаю.
...
Рейтинг: 0 / 0
20.03.2018, 14:59
    #39617585
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
Dima Tjenya7пропущено...

Придется делать парсинг формата как в printf() а это уже через чур.
Что в этом сложного? По ссылке пример как это делается.
аю я понял. спасибо.
...
Рейтинг: 0 / 0
20.03.2018, 15:11
    #39617605
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
d7iНе забывайте при каждой записи в лог-файл сперва писать в начале строки текущую дату и время.
Весьма полезно. Я всегда так делаю.
у меня с этим возникла проблема. не знаю как инициализировать начальную дату. у меня есть счетчик милисекунд. полноценного RTC нет. ну я тут накропал что то вроде
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
uint32_t LOG_InitTimeStamp(uint32_t day, uint32_t hours, uint32_t minutes, uint32_t seconds)
{
    uint32_t milliseconds = (day*3600*24) + (hours*3600) + (minutes*60) + seconds;
    
    return milliseconds; 
}

void LOG_GetTimeStamp(uint32_t timestamp, LOG_PARAMS *log_par)
{
	log_par->days = timestamp / (3600*24);
	log_par->hours = (timestamp - log_par->days) / 3600;
	log_par->minutes = (timestamp - log_par->days - log_par->hours) / 60;
	log_par->seconds  = timestamp - log_par->days - log_par->hours -  log_par->minutes;
}

void LOG_SetTimeStamp(char *time_str)
{
	char sval[10];
	
	uint32_t ts = get_Current_FPGA_Timer();
	glob_millisec += ts;
	
	LOG_GetTimeStamp(glob_millisec, &log_params);
	
	ItoA(log_params.days, sval);
	strcat(time_str, sval);
	strcat(time_str, ":");
	ItoA(log_params.hours, sval);
	strcat(time_str, sval);
	strcat(time_str, ":");
	ItoA(log_params.minutes, sval);
	strcat(time_str, sval);
	strcat(time_str, ":");
	ItoA(log_params.seconds, sval);
	strcat(time_str, sval);
	strcat(time_str, ":");
}
...
Рейтинг: 0 / 0
20.03.2018, 15:19
    #39617615
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
jenya7у меня есть счетчик милисекунд. полноценного RTC нет Date and Time on the Internet: Timestamps .
Прочитать надо всё, а примеры кода - в приложениях.
...
Рейтинг: 0 / 0
20.03.2018, 15:55
    #39617643
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
Basil A. Sidorov,

это эмбедед система.
...
Рейтинг: 0 / 0
20.03.2018, 16:07
    #39617654
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
jenya7это эмбедед система.Тогда не парьтесь и либо выводить миллисекунды аптайма или загрубляйте до секунд.
...
Рейтинг: 0 / 0
20.03.2018, 17:33
    #39617719
d7i
d7i
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
jenya7,
а что
VOID GetSystemTime(
LPSYSTEMTIME lpSystemTime // address of system time structure
);

уже отменили?
...
Рейтинг: 0 / 0
20.03.2018, 17:52
    #39617730
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
d7ijenya7,
а что
VOID GetSystemTime(
LPSYSTEMTIME lpSystemTime // address of system time structure
);

уже отменили?
у меня такого нет.
...
Рейтинг: 0 / 0
20.03.2018, 18:24
    #39617749
d7i
d7i
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
jenya7d7ijenya7,
а что
VOID GetSystemTime(
LPSYSTEMTIME lpSystemTime // address of system time structure
);

уже отменили?
у меня такого нет.

Вы пишите не для Windows?
Ну, всё равно должна же быть какая-то функция для получения системной даты и времени?
В любой ОС (API, библиотеки) такие есть. Поищите внимательней.
...
Рейтинг: 0 / 0
20.03.2018, 18:50
    #39617761
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
d7ijenya7пропущено...

у меня такого нет.

Вы пишите не для Windows?
Ну, всё равно должна же быть какая-то функция для получения системной даты и времени?
В любой ОС (API, библиотеки) такие есть. Поищите внимательней.
стал бы я писать под Windows на С? Я что больной на голову? :)
...
Рейтинг: 0 / 0
20.03.2018, 19:18
    #39617777
d7i
d7i
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
jenya7стал бы я писать под Windows на С? Я что больной на голову? :)
Хм, это для холодильника что ли?
Поясните уж...
...
Рейтинг: 0 / 0
20.03.2018, 19:32
    #39617793
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
d7ijenya7стал бы я писать под Windows на С? Я что больной на голову? :)
Хм, это для холодильника что ли?
Поясните уж...
это эмбедед система. контролер. vxWorks.
...
Рейтинг: 0 / 0
20.03.2018, 19:46
    #39617804
d7i
d7i
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
jenya7,
ну так, как советовали выше, не парьтесь с датой,
посчитайте что сможете (число дней, время и т.п.).
Главное, чтобы можно было как-то идентифицировать
временной промежуток между разными строками лога...
...
Рейтинг: 0 / 0
20.03.2018, 22:24
    #39617861
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Логирование данных в файл на С.
jenya71. Прежде всего проверить есть ли место на SD - вопрос как это сделать? и если нет места? очистить файл и начать писать сначала?

Поскольку это embed то надо смотреть в сторону ваших embed-нутых библиотек на C.
Я не знаю.. ну может по требованиям подойдет log4c или нечто подобное.

В классике логгирования держат пул файлов в ротации. Например 5 штук по 20Мб.
Пишут по кругу. Достаточно для разбора полетов если что-то упало.
2. Если файл открыт - добавить данные в файл, посмотреть флаг закрыть файл или нет.(я не хочу часто дергать файл - открывать\закрывать)

Это вопрос больше дизайна чем перформанса. Я думаю что для С на SD носителе
и на хорошей файловой системе типа (ext3) открытие файла будет очень быстрым.

Ну.. яб попробовал.
тогда что - держать глобальный указатель на файл?

3.Если файл закрыт - открыть с опцией "а+", добавить данные в файл, посмотреть флаг закрыть файл или нет.
Как вообще сделать покрасивше?
Тут надо просто пойти от самого приложения. Если ему доступны глобальные переменные - то почему нет.
Есть мультипоточность или нет. Поддерживаются ли файловые блокировки или нет. Вобщем сделать
несколько проб.

И соптимизировать место. По сути вам не нужно писать текст месседжа. Достаточно его код и атрибуты.
...
Рейтинг: 0 / 0
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Логирование данных в файл на С. / 25 сообщений из 26, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]