| Qui est en ligne ? |
| Il y a : 23 utilisateurs en ligne, consultez le détail |
Forum » Serveur, Réseaux et Programmation » log tournants en C |
Forum modéré par : jblecanard |
| Même auteur |
|
Score ( voter ) : |
|
| Page : [1] |
| Auteur | Message |
|---|---|
|
|
#0 Message posté le : 14-12-2007 à 14:01:17 |
Hobbit Forum : Modérateur Association : Membre actif Arrivé(e) le : 11-08-2003 Nombre de messages : 1533 |
Salut les gens, je cherche un bout de code qui permet d'ecrire des logs dans un fichier, mais de sorte à ce que le fichier ne fasse pas plus de 1 Mo par ex, et qu'on écrase à chaque fois les logs les plus anciens... pour écrire dans le fichier, no soucis pour vérifier la taille du fichier, Ok par contre, je ne sais pas comment faire pour effacer les logs anciens pour les remplacer par les nouveaux... une idée Merci ------------------------------------- |
|
|
#1 Message posté le : 14-12-2007 à 17:24:24 |
Hobbit Forum : Inscrit Association : Arrivé(e) le : 18-04-2005 Nombre de messages : 1219 |
salut.. 1. pour "effacer un fichier ": echo -n > le_fichier 2. pour "effacer les logs anciens pour les remplacer par les nouveaux..": je ne sais pas. en esperant une autre contribution.. selim,b. ------------------------------------- http://s.bouras.free.fr/citaPop-Up/ |
|
|
#2 Message posté le : 14-12-2007 à 18:19:36 |
Hobbit Forum : Inscrit Association : Arrivé(e) le : 17-10-2003 Nombre de messages : 1067 |
logrotate fait ça très bien sans commencer à coder en C directement. Apres pas compliqué : rotation de log sur 10 fichiers (algo basique) :
int max = 10;
int i;
for(i=max;i>0;i--)
{
if(i == max)
{
supprimer log.(i)
}
bouger log.(i-1) log.(i)
}
Pour supprimer un fichier : http://c.developpez.com/faq/?page=fichiers#FICHIERS_delete_POSIX Pour renommer un fichier : #include <stdio.h> int status; status = rename("/home/cnd/mod1", "/home/cnd/mod2"); http://www.opengroup.org/onlinepubs/009695399/functions/rename.html --Message édité par tamiel le 14-12-2007 à 18:19:58-- ------------------------------------- If you don't know, ask manpage ! |
|
|
#3 Message posté le : 14-12-2007 à 19:06:18 |
Naboo Forum : Modérateur Association : Président Arrivé(e) le : 09-04-2006 Nombre de messages : 2085 |
Si j'ai bien compris, tu veux que ton fichiers fasse toujours n entrées, sans devoir le vider entièrement quand tu entre l'entrée lambda*n+1. À ma connaissance, tu ne peux pas supprimer une partie d'un fichier directement : tu dois le recréer et tout remettre dedans, sauf cette entrée. Ce que tu peux faire, c'est définir une taille fixe l pour tes entrées et utiliser le fichier comme une taure : quand tu arrives à la fin (entrée n / EOF), tu reviens (fseek) au début pour réécrire sur les anciennes entrées. Afin de simplifier la lecture, tu peux faire commencer chaque entrée par un id%n (en ASCII) : un simple sort te permettra alors de lire le fichier "normalement" (i.e. linéairement). Tu peux détecter le débordement à l'aide d'un paramètre (ici appele n) ou simplement lorsque tu buttes sur la fin de fichier (ce qui nécessite de créer un fichier de bonne taille à la base). Avec la première idée tu auras besoin d'écrire la taille dans le fichier (ce qui fait une ligne en plus) mais cela te permet de réinitialiser les id ; avec la seconde méthodes, les ids vont irrémédiablement finir par déborder... c'est à toi de voir. édit : je propose de fixer la taille d'une entrée (qui sera complétée par des zéros ou tronquée s'il le faut) car cela permettra des réécritures écrasantes simples. Si tu ne peux définir de taille, tu peux mettre en place des mécanismes plus complexes ; le principe est simple d'écraser les anciennes entrées par un fwrite, de taille variable ou non. --Message édité par Azollyx le 14-12-2007 à 19:09:34-- ------------------------------------- toto |
|
|
#4 Message posté le : 17-12-2007 à 21:01:51 |
Hobbit Forum : Modérateur Association : Membre actif Arrivé(e) le : 11-08-2003 Nombre de messages : 1533 |
bonjour les gens, alors, dans le désordre : 1 - je dois faire cela en C, car c'est pour intégrer dans un soft qui tourne sur une carte élecronique en embarqué 2 - logrotate, echo & tous les autres commandes classiques shell, faut éviter, car je suis sous busybox, et c'est pas garanti que j'ai tout ce qu'il faut. En fait, voici un exemple de log que je voudrais - soit un fichier de logs qui ne doit pas faire plus de 4 lignes : au moment n : lundi 10 janvier 9:52 - client deconnecte lundi 10 janvier 9:50 - client connecte lundi 10 janvier 9:00 - firewall desactive lundi 10 janvier 8:00 - demarrage appli au moment n+1 : lundi 10 janvier 10:03 - deconnection lundi 10 janvier 9:52 - client deconnecte lundi 10 janvier 9:50 - client connecte lundi 10 janvier 9:00 - firewall desactive merci à vous ------------------------------------- |
|
|
#5 Message posté le : 17-12-2007 à 22:06:25 |
Jedi Forum : Modérateur Association : Membre fondateur Arrivé(e) le : 08-01-2005 Nombre de messages : 4030 |
Je trouve l'idée d'Azollyx très bonne pour éviter de réécrire le fichier. Si le nombre n est petit, le tri sera en plus rapide... Il n'y a pas 36 solution si on réfléchit à un niveau assez proche de la machine : décaler les données dans un fichier est aussi coûteux que de le réécrire. Il faut donc soit choisir de le réécrire, ce qui est plus coûteux à l'écriture mais plus léger à la lecture, soit choisir le tri (comme celui proposé par Azollyx), dans le quel cas l'écriture sera plus légère mais le lecture un peu plus coûteuse en calcul. Azollyx > attention, ta méthode ne fonctionne que si tu fixes une taille précise pour chaque ligne, même si tu utilises un paramètre contenant le nombre de lignes enregistrées. En effet, sur le disque dur, un caractère de retour à la ligne ou de fin de chaîne ne marque aucunement une coupure sur le fichier. Si tu ne fixe pas une taille par défaut et que tu tente d'écrire une ligne plus grande que celle que tu écrases, toute la fin du fichier devra être décalée depuis cette ligne... ------------------------------------- C'est une situation bien inconfortable que d'être assez sensible à la bêtise pour en souffrir et trop intelligent pour s'en indigner. - Gustave Thibon - |
|
|
#6 Message posté le : 17-12-2007 à 22:46:07 |
Naboo Forum : Modérateur Association : Président Arrivé(e) le : 09-04-2006 Nombre de messages : 2085 |
Je n'avais peut-être pas insisté dessu mais je l'avais dit.
Mais, comme mis en édit, ça n'est pas une nécessité : ce qui compte, c'est de ne pas réécrire plus que ce qu'on l'on peut, par segment. Tu peux donc prévoir une taille variable sachant que les premiers enregistrements définiront la taille max des prochaines réécritures... sauf si on en mange un complet... C'est réalisable, mais je pense qu'on perdrais effectivement en algorithme ce qu'on gagnerait en performances, sans parler du débugage. ------------------------------------- toto |
|
|
#7 Message posté le : 17-12-2007 à 23:21:48 |
Jedi Forum : Modérateur Association : Membre fondateur Arrivé(e) le : 08-01-2005 Nombre de messages : 4030 |
Arf j'avais compris que tu proposais une solution avec taille fixe et une sans... au temps pour moi ! ------------------------------------- C'est une situation bien inconfortable que d'être assez sensible à la bêtise pour en souffrir et trop intelligent pour s'en indigner. - Gustave Thibon - |
|
|
#8 Message posté le : 18-12-2007 à 17:41:32 |
Hobbit Forum : Inscrit Association : Arrivé(e) le : 17-10-2003 Nombre de messages : 1067 |
Un code de base en C (ça marche pour des logs de quelques lignes) ATTENTION : à chaque appel de log_init(), le fichier est effacé !!
#include <stdio.h>
#include <time.h>
#include <sys/stat.h>
#define LENLINE 100
#define MAXLINE 4
#define E_OPEN -1
#define OK 0
char *logfile;
FILE *fp;
int countlines = 1;
int log_init(char *filepath)
{
logfile = filepath;
fp = fopen(logfile, "w+");
if(fp == NULL)
{
return E_OPEN;
}
fclose(fp);
return OK;
}
int log_msg(char *msg)
{
struct tm *loctime;
time_t curtime;
char datestr[20];
char message[LENLINE];
char buffer[MAXLINE][LENLINE];
// set date
curtime = time(NULL);
loctime = localtime(&curtime);
strftime(datestr, LENLINE, "%Y%m%d %H:%M:%S", loctime);
// build formatted message
snprintf(message, LENLINE+20, "%s %s\n", datestr, msg);
if(countlines > MAXLINE)
{
unsigned int i=0;
fp = fopen(logfile, "r+");
while((fgets(buffer[i], (LENLINE-1), fp)) != NULL)
{
i++;
if(i == MAXLINE)
{
break;
}
}
rewind(fp);
unsigned int a;
for(a=1; a<MAXLINE;a++)
{
if(buffer[a] != NULL)
{
fprintf(fp, "%s", buffer[a]);
}
}
fprintf(fp, "%s", message);
fclose(fp);
}
else
{
fp = fopen(logfile, "a+");
fprintf(fp, "%s", message);
fclose(fp);
}
countlines++;
}
int main(int argc, char* argv[])
{
if( log_init("test.log") == E_OPEN)
{
printf("Error opening file\n");
}
log_msg("bonjour 1:)");
log_msg("bonjour 2:)");
log_msg("bonjour 3:)");
log_msg("bonjour 4:)");
log_msg("bonjour 5:)");
log_msg("bonjour 6:)");
log_msg("bonjour 7:)");
log_msg("bonjour 8:)");
log_msg("bonjour 9:)");
log_msg("bonjour 10:)");
return 0;
}
--Message édité par tamiel le 19-12-2007 à 09:48:37-- ------------------------------------- If you don't know, ask manpage ! |
|
|
#9 Message posté le : 18-12-2007 à 21:30:46 |
Naboo Forum : Modérateur Association : Président Arrivé(e) le : 09-04-2006 Nombre de messages : 2085 |
Oui mais là tu décales toutes les lignes, non ? ------------------------------------- toto |
|
|
#10 Message posté le : 19-12-2007 à 09:46:45 |
Hobbit Forum : Inscrit Association : Arrivé(e) le : 17-10-2003 Nombre de messages : 1067 |
Oui je décale mais ça correspond au besoin initial sans partir dans des algos compliqués pour rien : 4ème règle de Notes on Programming in C de Pike : Rule 4: Fancy algorithms are buggier than simple ones, and they are much harder to implement. Use simple algorithms as well as simple data structures. Je recois un log : - si le fichier ne fait pas le nombre max de lignes : j'insère la ligne en bas du fichier (je comprends pas pourquoi insérer la ligne en haut, c'est pas le sens de lecture occidental classique ) - si le fichier fait le nombre max de lignes je mets le contenu du fichier dans un buffer, je réécris le fichier en omettant la première ligne du buffer et en rajoutant la nouvelle ligne de log à la fin. C'est pour ça que je dis que ça va pour un log de quelques lignes (à mon avis avec 35000 lignes ça doit être coûteux en terme de buffer) --Message édité par tamiel le 19-12-2007 à 16:08:24-- ------------------------------------- If you don't know, ask manpage ! |
| Page : [1] |
Forum » Serveur, Réseaux et Programmation » log tournants en C |
Forum modéré par : jblecanard |
| Même auteur |
|
Score ( voter ) : |
|
- Petit scarabée : 0 pastille, moins de 100 messages
- Scarabée : 0 pastille, plus de 100 messages
- Hobbit : 1 pastille, plus de 1000 messages
- Naboo : 2 pastilles, plus de 2000 messages
- Elfe : 3 pastilles, plus de 3000 messages
- Jedi : 4 pastilles, plus de 4000 messages
- Maître Jedi : 5 pastilles, plus de 5000 messages