darshan-parser.c 6.92 KB
Newer Older
1
/*
2
3
4
 * Copyright (C) 2015 University of Chicago.
 * See COPYRIGHT notice in top-level directory.
 *
5
6
 */

7
8
9
10
11
12
13
14
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <zlib.h>
#include <time.h>
15
#include <stdlib.h>
16
#include <getopt.h>
17
#include <assert.h>
18

19
#include "uthash-1.9.2/src/uthash.h"
20

21
#include "darshan-logutils.h"
22

23
24
25
int main(int argc, char **argv)
{
    int ret;
26
    int i, j;
27
    char *filename;
28
    char tmp_string[4096];
29
30
31
32
33
    darshan_fd fd;
    struct darshan_header header;
    struct darshan_job job;
    struct darshan_record_ref *rec_hash = NULL;
    struct darshan_record_ref *ref;
34
35
36
    int mount_count;
    char** mnt_pts;
    char** fs_types;
37
    time_t tmp_time = 0;
38
39
    char *token;
    char *save;
40
    char buffer[DARSHAN_JOB_METADATA_LEN];
41
    int empty_mods = 0;
42

43
44
45
    /* TODO: argument parsing */
    assert(argc == 2);
    filename = argv[1];
46

47
48
    fd = darshan_log_open(filename, "r");
    if(!fd)
49
    {
50
        fprintf(stderr, "darshan_log_open() failed to open %s\n.", filename);
51
52
        return(-1);
    }
53
54
55

    /* read darshan log header */
    ret = darshan_log_getheader(fd, &header);
56
    if(ret < 0)
57
    {
58
59
        fprintf(stderr, "darshan_log_getheader() failed to read log header.\n");
        darshan_log_close(fd);
60
61
62
        return(-1);
    }

63
64
65
66
67
68
69
70
    /* read darshan job info */
    ret = darshan_log_getjob(fd, &job);
    if(ret < 0)
    {
        fprintf(stderr, "darshan_log_getjob() failed to read job data.\n");
        darshan_log_close(fd);
        return(-1);
    }
71

72
73
    /* get the original command line for this job */
    ret = darshan_log_getexe(fd, tmp_string);
74
    if(ret < 0)
75
    {
76
        fprintf(stderr, "Error: unable to read trailing job information.\n");
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
        darshan_log_close(fd);
        return(-1);
    }

    /* get the mount information for this log */
    ret = darshan_log_getmounts(fd, &mnt_pts, &fs_types, &mount_count);
    if(ret < 0)
    {
        fprintf(stderr, "darshan_log_getmounts() failed to read mount information.\n");
        darshan_log_close(fd);
        return(-1);
    }

    /* read hash of darshan records */
    ret = darshan_log_gethash(fd, &rec_hash);
    if(ret < 0)
    {
        fprintf(stderr, "darshan_log_getmap() failed to read record map.\n");
        darshan_log_close(fd);
96
97
98
        return(-1);
    }

99
    /* print job summary */
100
    printf("# darshan log version: %s\n", header.version_string);
101
    printf("# exe: %s\n", tmp_string);
Philip Carns's avatar
Philip Carns committed
102
103
104
    printf("# uid: %" PRId64 "\n", job.uid);
    printf("# jobid: %" PRId64 "\n", job.jobid);
    printf("# start_time: %" PRId64 "\n", job.start_time);
105
    tmp_time += job.start_time;
106
    printf("# start_time_asci: %s", ctime(&tmp_time));
Philip Carns's avatar
Philip Carns committed
107
    printf("# end_time: %" PRId64 "\n", job.end_time);
108
109
    tmp_time = 0;
    tmp_time += job.end_time;
110
    printf("# end_time_asci: %s", ctime(&tmp_time));
Philip Carns's avatar
Philip Carns committed
111
112
    printf("# nprocs: %" PRId64 "\n", job.nprocs);
    printf("# run time: %" PRId64 "\n", job.end_time - job.start_time + 1);
113
114
115
116
117
    for(token=strtok_r(job.metadata, "\n", &save);
        token != NULL;
        token=strtok_r(NULL, "\n", &save))
    {
        char *key;
118
119
120
121
122
123
124
125
126
127
128
129
130
131
        char *value;
        /* NOTE: we intentionally only split on the first = character.
         * There may be additional = characters in the value portion
         * (for example, when storing mpi-io hints).
         */
        strcpy(buffer, token);
        key = buffer;
        value = index(buffer, '=');
        if(!value)
            continue;
        /* convert = to a null terminator to split key and value */
        value[0] = '\0';
        value++;
        printf("# metadata: %s = %s\n", key, value);
132
    }
133

134
135
136
137
138
139
140
    /* print breakdown of each log file component's contribution to file size */
    printf("\n# log file component sizes (decompressed)\n");
    printf("# -------------------------------------------------------\n");
    printf("# header: %zu bytes\n", sizeof(struct darshan_header));
    printf("# job data: %zu bytes\n", sizeof(struct darshan_job));
    printf("# record table: %zu bytes\n", header.rec_map.len);
    for(i=0; i<DARSHAN_MAX_MODS; i++)
141
    {
142
        if(header.mod_map[i].len)
143
        {
144
145
            printf("# %s module: %zu bytes\n", darshan_module_names[i],
                header.mod_map[i].len);
146
        }
147
148
    }

149
150
151
    /* print table of mounted file systems */
    printf("\n# mounted file systems (mount point and fs type)\n");
    printf("# -------------------------------------------------------\n");
152
153
    for(i=0; i<mount_count; i++)
    {
154
        printf("# mount entry:\t%s\t%s\n", mnt_pts[i], fs_types[i]);
155
    }
156

157
    DARSHAN_PRINT_HEADER();
158

159
    for(i=0; i<DARSHAN_MAX_MODS; i++)
160
    {
161
162
        void *rec_p = NULL;
        darshan_record_id rec_id;
163

164
165
        /* skip modules not present in log file */
        if(header.mod_map[i].len == 0)
166
        {
167
168
169
            empty_mods++;
            if(empty_mods == DARSHAN_MAX_MODS)
                printf("# no module data available.\n");
170

171
            continue;
172
173
        }

174
175
        /* skip modules with no defined logutil handlers */
        if(!mod_logutils[i])
176
        {
177
178
179
            fprintf(stderr, "Warning: no log utility handlers defined "
                "for module %s, SKIPPING\n", darshan_module_names[i]);
            continue;
180
181
        }

182
        /* this module has data to be parsed and printed */
183

184
        /* TODO: do modules print header of what each counter means??? */
185

186
187
188
189
190
        /* loop over each of this module's records and print them */
        while ((ret = mod_logutils[i]->log_get_record(fd, &rec_p, &rec_id)) == 1)
        {
            char *mnt_pt = NULL;
            char *fs_type = NULL;
Philip Carns's avatar
Philip Carns committed
191

192
193
194
            /* get the pathname for this record */
            HASH_FIND(hlink, rec_hash, &rec_id, sizeof(darshan_record_id), ref);
            assert(ref);
195

196
197
            /* get mount point and fs type associated with this record */
            for(j=0; j<mount_count; j++)
198
            {
199
200
201
202
203
204
                if(strncmp(mnt_pts[j], ref->rec.name, strlen(mnt_pts[j])) == 0)
                {
                    mnt_pt = mnt_pts[j];
                    fs_type = fs_types[j];
                    break;
                }
205
            }
206
207
208
209
            if(!mnt_pt)
                mnt_pt = "UNKNOWN";
            if(!fs_type)
                fs_type = "UNKNOWN";
210

211
212
213
            /* print the corresponding module data for this record */
            mod_logutils[i]->log_print_record(rec_p, ref->rec.name,
                mnt_pt, fs_type);
214

215
216
            /* NOTE: we have to free the given file record data */
            free(rec_p);
217
218
        }

219
        if(ret < 0)
220
        {
221
222
223
224
225
            fprintf(stderr, "Error: failed to parse module %s data\n",
                darshan_module_names[i]);
            fflush(stderr);
            darshan_log_close(fd);
            return(-1);
226
227
228
        }
    }

229
230
    /* free mount info */
    for(i=0; i<mount_count; i++)
231
    {
232
233
        free(mnt_pts[i]);
        free(fs_types[i]);
234
    }
235
    if(mount_count > 0)
236
    {
237
238
        free(mnt_pts);
        free(fs_types);
239
240
    }

241
    darshan_log_close(fd);
242

243
    return(0);
244
}